From f9fa17ef77a99bdf461144b45c90f11dcaa69228 Mon Sep 17 00:00:00 2001 From: MarsBarLee <46167686+MarsBarLee@users.noreply.github.com> Date: Tue, 7 Feb 2023 16:28:23 -0500 Subject: [PATCH 1/2] Add file --- apps/labs/posts/ibis-1.3-release.md | 856 ++++++++++++++++++ ...7141ab17cfaa94c0a1cad75849b5d1763fcae1.svg | 1 + ...d7d60365fe2da629b5103143e73bfea0b6f39f.png | Bin 0 -> 2272 bytes ...40bcc66b7071e11bb0db32b0142239a2336085.png | Bin 0 -> 27688 bytes ...67cb659b1067258d29fbe649755a2e848e108a.png | Bin 0 -> 4953 bytes ...98cb83ec33da5b0824391dc456c3cf654cbd89.png | Bin 0 -> 9401 bytes ...dc92a22b0ccd022331e7a05bda2e0793922b6b.png | Bin 0 -> 2484 bytes ...a0adc684226342999e42956c4bb303dedd9595.svg | 1 + 8 files changed, 858 insertions(+) create mode 100644 apps/labs/posts/ibis-1.3-release.md create mode 100644 apps/labs/public/posts/ibis-1.3-release/227141ab17cfaa94c0a1cad75849b5d1763fcae1.svg create mode 100644 apps/labs/public/posts/ibis-1.3-release/29d7d60365fe2da629b5103143e73bfea0b6f39f.png create mode 100644 apps/labs/public/posts/ibis-1.3-release/5040bcc66b7071e11bb0db32b0142239a2336085.png create mode 100644 apps/labs/public/posts/ibis-1.3-release/6567cb659b1067258d29fbe649755a2e848e108a.png create mode 100644 apps/labs/public/posts/ibis-1.3-release/6a98cb83ec33da5b0824391dc456c3cf654cbd89.png create mode 100644 apps/labs/public/posts/ibis-1.3-release/8ddc92a22b0ccd022331e7a05bda2e0793922b6b.png create mode 100644 apps/labs/public/posts/ibis-1.3-release/fba0adc684226342999e42956c4bb303dedd9595.svg diff --git a/apps/labs/posts/ibis-1.3-release.md b/apps/labs/posts/ibis-1.3-release.md new file mode 100644 index 000000000..4d69f57f6 --- /dev/null +++ b/apps/labs/posts/ibis-1.3-release.md @@ -0,0 +1,856 @@ +--- +title: "Highlights of the Ibis 1.3 release" +author: ivan-ogasawara +published: May 2, 2020 +description: 'Ibis 1.3 was just released, after 8 months of development work, with 104 new commits from 16 unique contributors. In this blog post we will discuss some important features in this new version!' +category: [PyData ecosystem] +featuredImage: + src: /posts/hello-world-post/featured.png + alt: 'Excellent alt-text describing the featured image' +hero: + imageSrc: /posts/hello-world-post/hero.jpeg + imageAlt: 'Excellent alt-text describing the hero image' +--- + +Ibis 1.3 was just released, after 8 months of development work, with 104 +new commits from 16 unique contributors. What is new? In this blog post +we will discuss some important features in this new version! + +First, if you are new to the Ibis framework world, you can check this +[blog +post](https://labs.quansight.org/blog/2019/07/ibis-python-data-analysis-productivity-framework/) +I wrote last year, with some introductory information about it. + +Some highlighted features of this new version are: + +- Addition of a `PySpark` backend +- Improvement of geospatial support +- Addition of `JSON`, `JSONB` and `UUID` data types +- Initial support for `Python 3.8` added and support for `Python 3.5` + dropped +- Added new backends and geospatial methods to the documentation +- Renamed the `mapd` backend to `omniscidb` + +This blog post is divided into different sections: + +- OmniSciDB +- PostgreSQL +- PySpark +- Geospatial support +- Python versions support + +``` python +import ibis +import pandas as pd +``` + +### OmniSciDB + +The `mapd` backend is now named `omniscidb`! + +An important feature of `omniscidb` is that now you can define if the +connection is `IPC` (Inter-Process Communication), and you can also +specify the `GPU` device ID you want to use (if you have a NVIDIA card, +supported by `cudf`). + +`IPC` is used to provide shared data support between processes. +OmniSciDB uses Apache Arrow to provide IPC support. + +``` python +con_omni = ibis.omniscidb.connect( + host='localhost', + port='6274', + user='admin', + password='HyperInteractive', + database='ibis_testing', + ipc=False, + gpu_device=None +) +con_omni.list_tables() +``` + + ['diamonds', 'batting', 'awards_players', 'functional_alltypes', 'geo'] + +Also you can now specify `ipc` or `gpu_device` directly to the `execute` +method: + +``` python +t = con_omni.table('functional_alltypes') +expr = t[['id', 'bool_col']].head(5) +df = expr.execute(ipc=False, gpu_device=None) +df +``` + +```{=html} +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
idbool_col
06690True
16691False
26692True
36693False
46694True
+
+``` + +As you can imagine, the result of `df` is a `pandas.DataFrame` + +``` python +type(df) +``` + + pandas.core.frame.DataFrame + +But if you are using `gpu_device` the result would be a `cudf` :) + +``{=html} + +> Note: when `IPC=True` is used, the code needs to be executed on the +> same machine where the database is running +> +> Note: when `gpu_device` is used, 1) it uses IPC (see the note above) +> and 2) it needs a NVIDIA card supported by `cudf`. + +Another interesting feature is that now `omniscidb` also supports +`shapefiles` (input) and `geopandas` (output)! + +Check out the *Geospatial support* section below to see more details! + +Also the new version adds translations for more window operations for +the `omniscidb` backend, such as: `DenseRank`, `RowNumber`, `MinRank`, +`Count`, +[`PercentRank/CumeDist`](https://github.com/ibis-project/ibis/issues/1975). + +For more information about window operations, check the [Window +functions](https://docs.ibis-project.org/sql.html#window-functions) +documentation section. + +### PostgreSQL + +Some of the highlighted features for the `PostgreSQL` backend are new +data types included, such as: `JSON`, `JSONB` and `UUID`. + +``` python +from uuid import uuid4 +uuid_value = ibis.literal(uuid4(), type='uuid') +uuid_value == ibis.literal(uuid4(), type='uuid') +``` + +![](6a98cb83ec33da5b0824391dc456c3cf654cbd89.png) + +``` python +import json +json_value = ibis.literal(json.dumps({"id": 1}), type='json') +json_value +``` + +![](29d7d60365fe2da629b5103143e73bfea0b6f39f.png) + +``` python +jsonb_value = ibis.literal(json.dumps({"id": 1}).encode('utf8'), type='jsonb') +jsonb_value +``` + +![](8ddc92a22b0ccd022331e7a05bda2e0793922b6b.png) + +Another important new features on `PostgreSQL` backend is the support of +new `geospatial` operations, such as + +- GeometryType +- GeometryN +- IsValid +- LineLocatePoint +- LineMerge +- LineSubstring +- OrderingEquals +- Union + +Also, now it has support for two geospatial data types: `MULTIPOINT` and +`MULTILINESTRING`. + +Check out the *Geospatial support* section below to see some usage +examples of geospatial operations! + +### PySpark + +This new version also includes support for a new backend: **PySpark**! + +Let's do the first steps with this new backend starting with a Spark +session creation. + +``` python +import os + +import pyspark +from pyspark.sql import SparkSession +import pyspark.sql.types as pt +from pathlib import Path + +# spark session and pyspark connection +spark_session = SparkSession.builder.getOrCreate() +con_pyspark = ibis.pyspark.connect(session=spark_session) +``` + +We can use `spark` or `pandas` for reading from `CSV` file. In this +example, we will use `pandas`. + +``` python +data_directory = Path( + os.path.join( + os.path.dirname(ibis.__path__[0]), + 'ci', + 'ibis-testing-data' + ) +) + +pd_df_alltypes = pd.read_csv(data_directory / 'functional_alltypes.csv') +pd_df_alltypes.info() +``` + + + RangeIndex: 7300 entries, 0 to 7299 + Data columns (total 15 columns): + # Column Non-Null Count Dtype + --- ------ -------------- ----- + 0 index 7300 non-null int64 + 1 Unnamed: 0 7300 non-null int64 + 2 id 7300 non-null int64 + 3 bool_col 7300 non-null int64 + 4 tinyint_col 7300 non-null int64 + 5 smallint_col 7300 non-null int64 + 6 int_col 7300 non-null int64 + 7 bigint_col 7300 non-null int64 + 8 float_col 7300 non-null float64 + 9 double_col 7300 non-null float64 + 10 date_string_col 7300 non-null object + 11 string_col 7300 non-null int64 + 12 timestamp_col 7300 non-null object + 13 year 7300 non-null int64 + 14 month 7300 non-null int64 + dtypes: float64(2), int64(11), object(2) + memory usage: 855.6+ KB + +Now, we can create a Spark DataFrame and we will create a temporary view +from this data frame. Also we should enforce the desired types for each +column. + +``` python +def pyspark_cast(df, col_types): + for col, dtype in col_types.items(): + df = df.withColumn(col, df[col].cast(dtype)) + return df + +ps_df_alltypes = spark_session.createDataFrame(pd_df_alltypes) + +ps_df_alltypes = pyspark_cast( + ps_df_alltypes, { + 'index': 'integer', + 'Unnamed: 0': 'integer', + 'id': 'integer', + 'bool_col': 'boolean', + 'tinyint_col': 'byte', + 'smallint_col': 'short', + 'int_col': 'integer', + 'bigint_col': 'long', + 'float_col': 'float', + 'double_col': 'double', + 'date_string_col': 'string', + 'string_col': 'string', + 'timestamp_col': 'timestamp', + 'year': 'integer', + 'month': 'integer' + } +) + +# use ``SparkSession`` to create a table +ps_df_alltypes.createOrReplaceTempView('functional_alltypes') +con_pyspark.list_tables() +``` + + ['functional_alltypes'] + +Check if all columns were created with the desired data type: + +``` python +t = con_pyspark.table('functional_alltypes') +t +``` + +![](5040bcc66b7071e11bb0db32b0142239a2336085.png) + +Different than a `SQL` backend, that returns a `SQL` statement, the +returned `object` from the PySpark `compile` method is a PySpark +`DataFrame`: + +``` python +expr = t.head() +expr_comp = expr.compile() +type(expr_comp) +``` + + pyspark.sql.dataframe.DataFrame + +``` python +expr_comp +``` + + DataFrame[index: int, Unnamed: 0: int, id: int, bool_col: boolean, tinyint_col: tinyint, smallint_col: smallint, int_col: int, bigint_col: bigint, float_col: float, double_col: double, date_string_col: string, string_col: string, timestamp_col: timestamp, year: int, month: int] + +To convert the compiled expression to a Pandas `DataFrame`, you can use +the `toPandas` method. The result should be the same as that returned by +the `execute` method. + +``` python +assert all(expr.execute() == expr_comp.toPandas()) +``` + +``` python +expr.execute() +``` + +```{=html} +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
indexUnnamed: 0idbool_coltinyint_colsmallint_colint_colbigint_colfloat_coldouble_coldate_string_colstring_coltimestamp_colyearmonth
0006690True00000.00.011/01/1002010-11-01 00:00:00.000201011
1116691False111101.110.111/01/1012010-11-01 00:01:00.000201011
2226692True222202.220.211/01/1022010-11-01 00:02:00.100201011
3336693False333303.330.311/01/1032010-11-01 00:03:00.300201011
4446694True444404.440.411/01/1042010-11-01 00:04:00.600201011
+
+``` + +To finish this section, we can play a little bit with some aggregation +operations. + +``` python +expr = t +expr = expr.groupby('string_col').aggregate( + int_col_mean=t.int_col.mean(), + int_col_sum=t.int_col.sum(), + int_col_count=t.int_col.count(), +) +expr.execute() +``` + +```{=html} +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
string_colint_col_countint_col_meanint_col_sum
077307.05110
137303.02190
287308.05840
307300.00
457305.03650
567306.04380
697309.06570
717301.0730
847304.02920
927302.01460
+
+``` + +Check out the PySpark Ibis backend [API +documentation](https://docs.ibis-project.org/api.html#pyspark-client-experimental) +and the [tutorials](https://docs.ibis-project.org/tutorial.html) for +more details. + +### Geospatial support + +Currently, `ibis.omniscidb` and `ibis.postgres` are the only Ibis +backends that support geospatial features. + +In this section we will check some geospatial features using the +`PostgreSQL` backend. + +``` python +con_psql = ibis.postgres.connect( + host='localhost', + port=5432, + user='postgres', + password='postgres', + database='ibis_testing' +) +con_psql.list_tables() +``` + + ['array_types', + 'awards_players', + 'batting', + 'diamonds', + 'films', + 'functional_alltypes', + 'geo', + 'geography_columns', + 'geometry_columns', + 'intervals', + 'not_supported_intervals', + 'raster_columns', + 'raster_overviews', + 'spatial_ref_sys', + 'tzone'] + +Two important features are that it support `shape` objects (input) and +`geopandas` dataframe (output)! + +So, let's import `shapely` to create a simple `shape` point and +polygon. + +``` python +import shapely + +shp_point = shapely.geometry.Point((20, 10)) +shp_point +``` + +![](fba0adc684226342999e42956c4bb303dedd9595.svg) + +``` python +shp_polygon_1 = shapely.geometry.Polygon([(20, 10), (40, 30), (40, 20), (20, 10)]) +shp_polygon_1 +``` + +![](227141ab17cfaa94c0a1cad75849b5d1763fcae1.svg) + +Now, let's create a Ibis table expression to manipulate a \"geo\" +table: + +``` python +t_geo = con_psql.table('geo') +df_geo = t_geo.execute() +df_geo +``` + +```{=html} +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
idgeo_pointgeo_linestringgeo_polygongeo_multipolygon
01POINT (0.00000 0.00000)LINESTRING (0 0, 1 1)POLYGON ((30 10, 40 40, 20 40, 10 20, 30 10))(POLYGON ((30 20, 45 40, 10 40, 30 20)), POLYG...
12POINT (1.00000 1.00000)LINESTRING (1 1, 2 2)POLYGON ((35 10, 45 45, 15 40, 10 20, 35 10), ...(POLYGON ((40 40, 20 45, 45 30, 40 40)), POLYG...
23POINT (2.00000 2.00000)LINESTRING (2 2, 3 3)POLYGON ((2 2, 3 3, 4 4, 5 5, 5 2, 2 2))(POLYGON ((2 2, 3 3, 4 4, 5 5, 5 2, 2 2)))
34POINT (3.00000 3.00000)LINESTRING (3 3, 4 4)POLYGON ((3 3, 4 4, 5 5, 6 6, 6 3, 3 3))(POLYGON ((3 3, 4 4, 5 5, 6 6, 6 3, 3 3)))
45POINT (4.00000 4.00000)LINESTRING (4 4, 5 5)POLYGON ((4 4, 5 5, 6 6, 7 7, 7 4, 4 4))(POLYGON ((4 4, 5 5, 6 6, 7 7, 7 4, 4 4)))
+
+``` + +And the type of `df_geo` is \... a `geopandas` dataframe! + +``` python +type(df_geo) +``` + + geopandas.geodataframe.GeoDataFrame + +So you can take the advantage of GeoPandas features too! + +``` python +df_geo.set_geometry('geo_multipolygon').head(1).plot(); +``` + +![](6567cb659b1067258d29fbe649755a2e848e108a.png) + +Now, let's check if there are any `geo_multipolygon`'s that contain +the `shape` point we just created. + +``` python +t_geo[ + t_geo.geo_multipolygon, + t_geo['geo_multipolygon'].contains(shp_point).name('contains_point_1') +].execute() +``` + +```{=html} +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
geo_multipolygoncontains_point_1
0MULTIPOLYGON (((30.00000 20.00000, 45.00000 40...True
1MULTIPOLYGON (((40.00000 40.00000, 20.00000 45...True
2MULTIPOLYGON (((2.00000 2.00000, 3.00000 3.000...False
3MULTIPOLYGON (((3.00000 3.00000, 4.00000 4.000...False
4MULTIPOLYGON (((4.00000 4.00000, 5.00000 5.000...False
+
+``` + +So, as expected, just the first two `multipolygon`s contain a `point` +with coordinates `(20, 10)`. + +For more examples of Geospatial Analysis with Ibis, check this nice +[tutorial](https://docs.ibis-project.org/notebooks/tutorial/11-Geospatial-Analysis.html) +written by [Ian Rose](https://github.com/ian-r-rose)! + +### Python versions support + +Ibis 1.3 added initial support for Python 3.8 and dropped support for +Python 3.5. + +> Note: currently, the +> [OmniSciDB](https://github.com/ibis-project/ibis/issues/2090) and +> [PySpark](https://github.com/ibis-project/ibis/issues/2091) backends +> are not supported on Python 3.8. + +### Final words + +**Do you want to play more with Ibis framework?** + +You can install it from PyPI: + + python -m pip install --upgrade ibis-framework==1.3.0 + +Or from conda-forge: + + conda install ibis-framework=1.3.0 -c conda-forge + +Check out some interesting tutorials to help you to start on Ibis: +. If you are coming from +the SQL world, maybe [Ibis for SQL +Programmers](https://docs.ibis-project.org/sql.html) documentation +section will be helpful. Have fun! + diff --git a/apps/labs/public/posts/ibis-1.3-release/227141ab17cfaa94c0a1cad75849b5d1763fcae1.svg b/apps/labs/public/posts/ibis-1.3-release/227141ab17cfaa94c0a1cad75849b5d1763fcae1.svg new file mode 100644 index 000000000..86b657e1d --- /dev/null +++ b/apps/labs/public/posts/ibis-1.3-release/227141ab17cfaa94c0a1cad75849b5d1763fcae1.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/apps/labs/public/posts/ibis-1.3-release/29d7d60365fe2da629b5103143e73bfea0b6f39f.png b/apps/labs/public/posts/ibis-1.3-release/29d7d60365fe2da629b5103143e73bfea0b6f39f.png new file mode 100644 index 0000000000000000000000000000000000000000..26db26cbcdba2fa21bd03c224df2a41fc9fd739c GIT binary patch literal 2272 zcmai0XIPWT7XAoD3;{tR1WAph7@FI^uqN?|tr{`(vMZX6F2uIdjT;&O7Nitfe4S5()r-ptTk1 z61ca5(~zGJToq*Z>EOoaX=8~3e*8U3+pBH?0Dqn}$_yV~$SL%*a_~6W`_#!NDsVTR zssQaO+vTbJM)I0fcNucl;5S>&8x|0dcPO`vD!ZRJBCoyO>F%3$?*rN!?R=VV@TzJu z5nVyO+Wg7&!O{kAsjJFTkI9w^~ zPf9(j0{PU*P@kEBpTmC~B8yGpRs}s&Z}TdgKHYDe`?{>Ijsld5w@2>nkI|J3}GP@myeJ`ztvoP{Oz^MJXi16sEx@s}?r5)r=VB?DULM4~+|}W9-%QrpZ3;3rkB$!iiZ~uz%l`r#q+$Bsg_zh-Gq^42nCB z7s7=|ef~V@2gC9&wdo12^DQ1;WflG>%c z&E=-hWwE*Wc{ySJM-dy|-?p~sjO&e(&=d%bMiYjn@WWszSJ#u+662ei9vx?9ULM5Y z)$^v>0~y{wwm4E43??Th2cS8_K&P8sDZSY;lPoM2JNLdhIE_N#D;ctMc1CQiv9q1( z-B}Z%VPQ!`1YBJFV$~>dwDM>0fgDUlQ`GiqCz;8j8HJ^%rO5(T=H{K6e%##L9E!ao z9zVhQx*MHuSr6gnzA`y7Vt-slW^Iho)HG4K`o|w)I-2_WtU=>*=WYp`znqyVwUP1C zrWUa=75^FtAdy1CRHqggIKw)cnnR!T3I@EH{@&iHD-*P?vLY)* zc{ew=np*dI6~M~hU*o8d5QDb4v7r#zK3#j*G#t?GB;WeV3nIsJz42Ye)WU)yznm|L zpKN|V7oeo1bQS>_scZ<3{0M z0Cc%XOiawnzP`@xZl1wH{cBEPetth;3-uE0N{or&;RqIsRY0X)nfSQ+;&ouUVeV80 zp_VMcsy(lxLnmV@-e|-{M&7vzmC_+SdUXx~Be62YHR+!k6rwN~D3wa3sa1{m^2?dr z!-s}mu(q*LAQFk)Y&Khi5E>FPar^sZZhL!sQ5s7AlDqq%h!vHe^7+iQBEpW(+vMQJhnXMk{_Z*?0Z>y@^Y!!V0WmI@hhepCE{{)6pi!u+Blj$H?AA;^lnC#W%tX!4 zB9WZoL6VN4tq0vJy(=WMC-LD!b->ir6nI!&EtlUfA}N_cr)$IEaJ@6SVRNtZ3kwU` zEv#f=uxO4vfBqaS9QPc?sodgXNsT7PD2V|2Z0k;_3F(vQ-xK(w2Dl?%n%`ab*0RfsY?m4b8wZ&n+q% zSPTsf)vvXa6`mN=@~CrdUbm4l=cmY+P{95W5)yLtLtoy8|6170#;%o}on>UC0Z>{| z!Mnf3>EcX2`F(xC8Zh3=HT+@0<-WD01NtR78Nb*zb~{ zn;>Q{T)5!t>l;Y$-x9q10FRKCCRe+K72LUF4#u$9C}M8pPk);8qu=Mzf8y1@ZEn)8 zxi~o;c}Bjp_O4OjS+-Isp*HoEmw8;ANlKf`s!b~I=mr3S4v zE)gJppC0H|-M_DRx8)|fe2M{IBq4>49lKRffXLsx-bi4^ZV6m>bj%x#Jptyb=C@C8 zDzHyJS5{V9;qkY-fZs7WtQVq6%C3gjg1|pVkb_p z8ec7KSQ7|$Tw-?Ee#n+g=QHTw;BySW$<&-2;T!#wFJA&bh8Vau1#(q8)u&o1CgN04 zwze=hly~g<1!k?w5_uBDJNn8MiMhEsSvXWgLL%KJUt@NK)qw5a+21d3Y&;RvTT(_u4diXfD*F#J{}ZMD z&EEfiCU7skzTAYn0(ZFP+eoO2!1mPPRE_3fDRVy|IxFh8)m#^)-5MP9xK9|SoWs#T l;n*`|fT3C00k8YP5vA>4(bX<%X5g0vu(rUW>ddbu{spxJGPeK# literal 0 HcmV?d00001 diff --git a/apps/labs/public/posts/ibis-1.3-release/5040bcc66b7071e11bb0db32b0142239a2336085.png b/apps/labs/public/posts/ibis-1.3-release/5040bcc66b7071e11bb0db32b0142239a2336085.png new file mode 100644 index 0000000000000000000000000000000000000000..be5de12de58cb8d9c0b96ac4f09326148ccc8f11 GIT binary patch literal 27688 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 Rz@xutj%w;_JW#g{{x6a;v^f9( literal 0 HcmV?d00001 diff --git a/apps/labs/public/posts/ibis-1.3-release/6567cb659b1067258d29fbe649755a2e848e108a.png b/apps/labs/public/posts/ibis-1.3-release/6567cb659b1067258d29fbe649755a2e848e108a.png new file mode 100644 index 0000000000000000000000000000000000000000..34d260e87f3505060c1ea4234c06dca34cf6532f GIT binary patch literal 4953 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 Cfvl4N literal 0 HcmV?d00001 diff --git a/apps/labs/public/posts/ibis-1.3-release/6a98cb83ec33da5b0824391dc456c3cf654cbd89.png b/apps/labs/public/posts/ibis-1.3-release/6a98cb83ec33da5b0824391dc456c3cf654cbd89.png new file mode 100644 index 0000000000000000000000000000000000000000..5d8801b781eab4d2c117891e498679750ae97190 GIT binary patch literal 9401 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 NQB~5wd{8tF_%Epm@MHi0 literal 0 HcmV?d00001 diff --git a/apps/labs/public/posts/ibis-1.3-release/8ddc92a22b0ccd022331e7a05bda2e0793922b6b.png b/apps/labs/public/posts/ibis-1.3-release/8ddc92a22b0ccd022331e7a05bda2e0793922b6b.png new file mode 100644 index 0000000000000000000000000000000000000000..9e7e3cda27506f9166263af0e973e4cc91b47407 GIT binary patch literal 2484 zcma)8X*k>I7XMpA?7Kz?s@leCjEmG#ilAbtJxX={^Wi@Cez+g*^FHr;KAiVC=Q-zhe&-y#{dG$LC=3b!fWTEN zGY3#o!E3<74ZgIS`M-gJ+v}R88SvxpQ`l0P2>`tJu9_J;M&@qJ_*;q3$w0nttxkE& zIFLi|Z$ftEUW&S(<1Gnj_H_xuvfJ_`c{s|yf=%t46QLFsVcU;ezCIz1TYHC-C+NNG zH+VV;Y91;B$4@qo+EVh`n8N{8**fu;5z@WdG`-N}b!4bFDetp1nm;LH+d3CM%VBcr z^a7rgQn(~PL3$RN0?ac?)Vc;muFE zy1Tna{2Fk~)mMqaBL6nPc@CnWctMXx#JJBmg~wXZ#LPZKSP}R9zrG}yW)?R!!Qj+{ zMct+4W&OH~NiI2cOZH`s^SXiq+3E%5%04ehBxU3%RZT)dB5iXDJ1{iFMZN#Fx;i|} zne%e=0Y99oaPcBDJpgNw>vYr6@vA2#RZ3mI$zTcbd1NW&=~H$zKS2|27&$_8k& zWbYn7FDTer-L&cLNQ87qn>sqaC~n?yekr02QAnH5Sh82ia#~q7ky_Hq0d3z|8P1Dw zb#M^%v@COU>pDC*P*hbFh>MHM=)=6!_7T(xpg&qz@T#C-KfUj33_U%Gy4@7Un~;zI z>UsG1Os`$zLsX1?DIE9vytO6t$8AApXJ<}MPI*1OGjpx6uRjovcA-#cC6bTqpN6;+ zH~+7)8$3`b&Y>*Hx&&uY+|d$!Sm~9VoP2+8^;Z^)Wu%hzVQfrnbaXWGXs5({1`M_R zK3q#n3#B1l8#Jrm%LsWp?svN_&b@vvD=X_{MMP8-x3ja;Cy*pereZc23`RFlTUc1= z+0)e2 zW(XY}#$jP$^2*BGK=9$FdwpZ0U5tiupYJ6_B_+;}A3utfBM=B$y3h6NX+!k7I<4QE zn~NzFNe&JU*2$4}c}0cDnKOOqQeQ)zT0>U^9aSWPW}6;^&gv-?MKv|S#Kc6at5?Z> z&9$|{5J9++kI#89_q7pQ9xrW_J3cP zoN3;&w&vGErxnjrs;*w;Tnwr{_IB4R{K5#=IXV5CIVW50vRA^44|;$n`uws;6&82e3J6we7d4-N^bW5s7v zC^{YAZZ!rq=C-WGqQ?%liX)zPyR#rw?>TL8eEtZBTE z4N_1*pu4x12N`$bOAgv!8<&iaj*7YircKfZ;_W|CNmkLG`~@4WlF}NBQNDxz^x}iG z*aS*SVP_BVz7H2{J0DzjB+V3F@=p~qdp`l^$!Mf{jBocH&rodNB0)bFx zF{INqpHw*4d>9%MKq8Sh>H-x+L`1-9w2Y0t?D0O5t;HjKZ!e4!0x2euxZnBEmXA5; zzX&d3t6ws;4d!s#H_<|a8B5a5ohFGONx4cK@TaG7W)>Dxv3p@5qWMPA42aiANw*gH2h#Y&Uk^$xd8Hmr_yz>5 ztIr{&;P8Oaa8J*I@jxV@Ics`+ygMc~Hjq*=$vk3_rIw5y?UiWpEx<%HOI!L z5eOPsEVkpJs;X*u`bL2l6Bpy_YZZ3;uGSfUKfeWZ;B0@^0AmoP@s+&Hw*vxQ5olfF zASov|{3EbcJ{^x2d7pL5&CTx+Nn`PafZ+D`TL;YiF0#3~i7PeUT^>s8Kp8nXNjg=! zust?m1LuUNr>Ad&+iIA8rCUS)W?+HteRdyOzPXVRuoR*vsqR5oq^2+S63@PQkeiox z|M(!#_Y&;XFou-bhZ$k+r=+JRyH!1LROxNuK`x7r{2#aUcG^rA2l&uZ{g2^-92cr#DD~$lYZDFEm;c`^nHU zVxvamY!Ku5ms0x+!V(fcqvM0F$X?Jpy|cV>FGWMYO4029SQq~H7n8m7OcQla<)t=@ zn#t5^F!1k@9099A6k7&er<>16;#^ NtLE3us!dS1zW`O~v~vIe literal 0 HcmV?d00001 diff --git a/apps/labs/public/posts/ibis-1.3-release/fba0adc684226342999e42956c4bb303dedd9595.svg b/apps/labs/public/posts/ibis-1.3-release/fba0adc684226342999e42956c4bb303dedd9595.svg new file mode 100644 index 000000000..fb8c8968c --- /dev/null +++ b/apps/labs/public/posts/ibis-1.3-release/fba0adc684226342999e42956c4bb303dedd9595.svg @@ -0,0 +1 @@ + \ No newline at end of file From 635feb12613ea6989db07aa125e7d006d2af6592 Mon Sep 17 00:00:00 2001 From: MarsBarLee <46167686+MarsBarLee@users.noreply.github.com> Date: Thu, 9 Feb 2023 16:32:12 -0500 Subject: [PATCH 2/2] Update hero and feature images --- apps/labs/posts/ibis-1.3-release.md | 22 +++++++++---------- .../ibis-1.3-release/blog_feature_var2.svg | 1 + .../posts/ibis-1.3-release/blog_hero_var2.svg | 1 + 3 files changed, 13 insertions(+), 11 deletions(-) create mode 100644 apps/labs/public/posts/ibis-1.3-release/blog_feature_var2.svg create mode 100644 apps/labs/public/posts/ibis-1.3-release/blog_hero_var2.svg diff --git a/apps/labs/posts/ibis-1.3-release.md b/apps/labs/posts/ibis-1.3-release.md index 4d69f57f6..4e05d1592 100644 --- a/apps/labs/posts/ibis-1.3-release.md +++ b/apps/labs/posts/ibis-1.3-release.md @@ -5,11 +5,11 @@ published: May 2, 2020 description: 'Ibis 1.3 was just released, after 8 months of development work, with 104 new commits from 16 unique contributors. In this blog post we will discuss some important features in this new version!' category: [PyData ecosystem] featuredImage: - src: /posts/hello-world-post/featured.png - alt: 'Excellent alt-text describing the featured image' + src: /posts/ibis-1.3-release/blog_feature_var2.svg + alt: 'An illustration of a brown and a white hand coming towards each other to pass a business card with the logo of Quansight Labs.' hero: - imageSrc: /posts/hello-world-post/hero.jpeg - imageAlt: 'Excellent alt-text describing the hero image' + imageSrc: /posts/ibis-1.3-release/blog_hero_var2.svg + imageAlt: 'An illustration of a dark brown hand holding up a microphone, with some graphical elements highlighting the top of the microphone.' --- Ibis 1.3 was just released, after 8 months of development work, with 104 @@ -178,7 +178,7 @@ uuid_value = ibis.literal(uuid4(), type='uuid') uuid_value == ibis.literal(uuid4(), type='uuid') ``` -![](6a98cb83ec33da5b0824391dc456c3cf654cbd89.png) +![A graph showing the relationship between Equals, Left and Right.](/posts/ibis-1.3-release/6a98cb83ec33da5b0824391dc456c3cf654cbd89.png) ``` python import json @@ -186,14 +186,14 @@ json_value = ibis.literal(json.dumps({"id": 1}), type='json') json_value ``` -![](29d7d60365fe2da629b5103143e73bfea0b6f39f.png) +![Literal pointing at json.](/posts/ibis-1.3-release/29d7d60365fe2da629b5103143e73bfea0b6f39f.png) ``` python jsonb_value = ibis.literal(json.dumps({"id": 1}).encode('utf8'), type='jsonb') jsonb_value ``` -![](8ddc92a22b0ccd022331e7a05bda2e0793922b6b.png) +![Literal pointing at jsonb.](/posts/ibis-1.3-release/8ddc92a22b0ccd022331e7a05bda2e0793922b6b.png) Another important new features on `PostgreSQL` backend is the support of new `geospatial` operations, such as @@ -318,7 +318,7 @@ t = con_pyspark.table('functional_alltypes') t ``` -![](5040bcc66b7071e11bb0db32b0142239a2336085.png) +![The data types for the pyspark.table.](/posts/ibis-1.3-release/5040bcc66b7071e11bb0db32b0142239a2336085.png) Different than a `SQL` backend, that returns a `SQL` statement, the returned `object` from the PySpark `compile` method is a PySpark @@ -649,14 +649,14 @@ shp_point = shapely.geometry.Point((20, 10)) shp_point ``` -![](fba0adc684226342999e42956c4bb303dedd9595.svg) +![A green dot.](/posts/ibis-1.3-release/fba0adc684226342999e42956c4bb303dedd9595.svg) ``` python shp_polygon_1 = shapely.geometry.Polygon([(20, 10), (40, 30), (40, 20), (20, 10)]) shp_polygon_1 ``` -![](227141ab17cfaa94c0a1cad75849b5d1763fcae1.svg) +![A green triangle.](/posts/ibis-1.3-release/227141ab17cfaa94c0a1cad75849b5d1763fcae1.svg) Now, let's create a Ibis table expression to manipulate a \"geo\" table: @@ -753,7 +753,7 @@ So you can take the advantage of GeoPandas features too! df_geo.set_geometry('geo_multipolygon').head(1).plot(); ``` -![](6567cb659b1067258d29fbe649755a2e848e108a.png) +![Two triangles on a graph](/posts/ibis-1.3-release/6567cb659b1067258d29fbe649755a2e848e108a.png) Now, let's check if there are any `geo_multipolygon`'s that contain the `shape` point we just created. diff --git a/apps/labs/public/posts/ibis-1.3-release/blog_feature_var2.svg b/apps/labs/public/posts/ibis-1.3-release/blog_feature_var2.svg new file mode 100644 index 000000000..b7533414b --- /dev/null +++ b/apps/labs/public/posts/ibis-1.3-release/blog_feature_var2.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/apps/labs/public/posts/ibis-1.3-release/blog_hero_var2.svg b/apps/labs/public/posts/ibis-1.3-release/blog_hero_var2.svg new file mode 100644 index 000000000..ff5d843c1 --- /dev/null +++ b/apps/labs/public/posts/ibis-1.3-release/blog_hero_var2.svg @@ -0,0 +1 @@ + \ No newline at end of file