Python Polars:惰性帧行计数不等于 wc -l

Han*_*aal 0 python python-polars

我一直在尝试的polars关键功能中,最让我感兴趣的是比 RAM操作更大的功能。

\n

我从这里下载了一些文件来玩。在网站上:每个文件的第一行是标题;1行对应1条记录。警告总下载量相当大(~1.3GB)!本实验在AWS服务器上完成( t2.medium,, 2cpu)4GB

\n
wget https://s3.amazonaws.com/amazon-reviews-pds/tsv/amazon_reviews_us_Shoes_v1_00.tsv.gz \\\nhttps://s3.amazonaws.com/amazon-reviews-pds/tsv/amazon_reviews_us_Office_Products_v1_00.tsv.gz \\\nhttps://s3.amazonaws.com/amazon-reviews-pds/tsv/amazon_reviews_us_Software_v1_00.tsv.gz \\\nhttps://s3.amazonaws.com/amazon-reviews-pds/tsv/amazon_reviews_us_Personal_Care_Appliances_v1_00.tsv  .gz \\\nhttps://s3.amazonaws.com/amazon-reviews-pds/tsv/amazon_reviews_us_Watches_v1_00.tsv.gz \n\ngunzip *\n
Run Code Online (Sandbox Code Playgroud)\n

以下是结果wc -l

\n
drwxrwxr-x 3 ubuntu ubuntu       4096 Jun  2 12:44 ../\n-rw-rw-r-- 1 ubuntu ubuntu 1243069057 Nov 25  2017 amazon_reviews_us_Office_Products_v1_00.tsv\n-rw-rw-r-- 1 ubuntu ubuntu   44891575 Nov 25  2017 amazon_reviews_us_Personal_Care_Appliances_v1_00.tsv\n-rw-rw-r-- 1 ubuntu ubuntu 1570176560 Nov 25  2017 amazon_reviews_us_Shoes_v1_00.tsv\n-rw-rw-r-- 1 ubuntu ubuntu  249565371 Nov 25  2017 amazon_reviews_us_Software_v1_00.tsv\n-rw-rw-r-- 1 ubuntu ubuntu  412542975 Nov 25  2017 amazon_reviews_us_Watches_v1_00.tsv\n\n$ find . -type f -exec cat {} + | wc -l\n8398139\n\n$ find . -name \'*.tsv\' | xargs wc -l\n   2642435 ./amazon_reviews_us_Office_Products_v1_00.tsv\n    341932 ./amazon_reviews_us_Software_v1_00.tsv\n     85982 ./amazon_reviews_us_Personal_Care_Appliances_v1_00.tsv\n   4366917 ./amazon_reviews_us_Shoes_v1_00.tsv\n    960873 ./amazon_reviews_us_Watches_v1_00.tsv\n   8398139 total\n
Run Code Online (Sandbox Code Playgroud)\n

polars现在,如果我使用我们新的奇特的惰性函数来计算行数:

\n
import polars as pl\n\ncsvfile = "~/data/amazon/*.tsv"\n(\n    pl.scan_csv(csvfile, separator = \'\\t\')\n    .select( \n        pl.count()\n        )\n    .collect()\n)\nshape: (1, 1)\n\xe2\x94\x8c\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x90\n\xe2\x94\x82 count   \xe2\x94\x82\n\xe2\x94\x82 ---     \xe2\x94\x82\n\xe2\x94\x82 u32     \xe2\x94\x82\n\xe2\x95\x9e\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\xa1\n\xe2\x94\x82 4186305 \xe2\x94\x82\n\xe2\x94\x94\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x98\n
Run Code Online (Sandbox Code Playgroud)\n

wc -l哇,这和之间有很大的区别polars。这很奇怪……也许是数据问题。让我们只关注感兴趣的列:

\n
csvfile = "~/data/amazon/*.tsv"\n(\n...     pl.scan_csv(csvfile, separator = \'\\t\')\n...     .select( \n...         pl.col("product_category").count()\n...         )\n...     .collect()\n... )\nshape: (1, 1)\n\xe2\x94\x8c\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x90\n\xe2\x94\x82 product_category \xe2\x94\x82\n\xe2\x94\x82 ---              \xe2\x94\x82\n\xe2\x94\x82 u32              \xe2\x94\x82\n\xe2\x95\x9e\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\xa1\n\xe2\x94\x82 7126095          \xe2\x94\x82\n\xe2\x94\x94\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x98\n
Run Code Online (Sandbox Code Playgroud)\n

.collect(streaming = True)

\n
shape: (1, 1)\n\xe2\x94\x8c\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x90\n\xe2\x94\x82 product_category \xe2\x94\x82\n\xe2\x94\x82 ---              \xe2\x94\x82\n\xe2\x94\x82 u32              \xe2\x94\x82\n\xe2\x95\x9e\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\xa1\n\xe2\x94\x82 7125569          \xe2\x94\x82\n\xe2\x94\x94\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x98\n
Run Code Online (Sandbox Code Playgroud)\n

好吧,还是相差100万左右?让我们从下往上做:

\n
csvfile = "~/data/amazon/*.tsv"\n(\n    pl.scan_csv(csvfile, separator = \'\\t\') \n    .groupby(["product_category"])\n    .agg(pl.col("product_category").count().alias("counts"))\n    .collect(streaming = True)\n    .filter(pl.col(\'counts\') > 100)\n    .sort(pl.col("counts"), descending = True)\n    .select(\n        pl.col(\'counts\').sum()\n    )\n)\nshape: (1, 1)\n\xe2\x94\x8c\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x90\n\xe2\x94\x82 counts  \xe2\x94\x82\n\xe2\x94\x82 ---     \xe2\x94\x82\n\xe2\x94\x82 u32     \xe2\x94\x82\n\xe2\x95\x9e\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\xa1\n\xe2\x94\x82 7125553 \xe2\x94\x82\n\xe2\x94\x94\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x98\n
Run Code Online (Sandbox Code Playgroud)\n

关闭,尽管它再次是一个不同的计数......

\n

使用以下命令进行更多检查R

\n
library(vroom)\nlibrary(purrr)\nlibrary(glue)\nlibrary(logger)\namazon <- list.files("~/data/amazon/", full.names = TRUE)\nf <- function(file){\n     df <- vroom(file, col_select = \'product_category\', show_col_types=FALSE )\n     log_info(glue("File [{basename(file)}] has [{nrow(df)}] rows"))\n}\n\nwalk(amazon, f)\nINFO [2023-06-02 14:23:40] File [amazon_reviews_us_Office_Products_v1_00.tsv] has [2633651] rows\nINFO [2023-06-02 14:23:41] File [amazon_reviews_us_Personal_Care_Appliances_v1_00.tsv] has [85898] rows\nINFO [2023-06-02 14:24:06] File [amazon_reviews_us_Shoes_v1_00.tsv] has [4353998] rows\nINFO [2023-06-02 14:24:30] File [amazon_reviews_us_Software_v1_00.tsv] has [331152] rows\nINFO [2023-06-02 14:24:37] File [amazon_reviews_us_Watches_v1_00.tsv] has [943763] rows\n\nTotal: 8348462\n
Run Code Online (Sandbox Code Playgroud)\n

好的。算了。基本上是一个随机数生成练习,没有什么是真实的。

\n

当然,如果是数据卫生问题,那么错误应该是恒定的吗?知道为什么会有这么大的差异吗?

\n

jqu*_*ous 5

在这种情况下,声明下载的大小通常很有帮助。

\n\n

我尝试 pandas 来调试它,它无法读取以下任何文件:

\n
pd.read_csv(\'amazon-reviews/amazon_reviews_us_Personal_Care_Appliances_v1_00.tsv\', sep=\'\\t\')\n
Run Code Online (Sandbox Code Playgroud)\n
ParserError: Error tokenizing data. C error: \n Expected 15 fields in line 1598, saw 22\n
Run Code Online (Sandbox Code Playgroud)\n

1598行:

\n
US  3878437 R3BH4UXFRP6F8L  B00J7G8EL0  381088677   GUM Expanding Floss - 30 m - 2 pk   Personal_Care_Appliances    \n4   0   0   N   Y   " like the REACH woven that\'s no longer available--THAT was the wish it was a bit &#34;fluffier,&#34; like the REACH woven that\'s no longer available--THAT was the best    2015-08-06\n
Run Code Online (Sandbox Code Playgroud)\n

问题是单个"字符,您需要禁用默认的引用行为。

\n

8398134通过这一更改,我得到了每次的总数。

\n
\n

极地

\n
(pl.scan_csv(\'amazon-reviews/*.tsv\', separator=\'\\t\', quote_char=None)\n   .select(pl.count())\n   .collect()\n)\n
Run Code Online (Sandbox Code Playgroud)\n
CPU times: user 3.65 s, sys: 2.02 s, total: 5.67 s\nWall time: 2.48 s\nshape: (1, 1)\n\xe2\x94\x8c\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x90\n\xe2\x94\x82 count   \xe2\x94\x82\n\xe2\x94\x82 ---     \xe2\x94\x82\n\xe2\x94\x82 u32     \xe2\x94\x82\n\xe2\x95\x9e\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\xa1\n\xe2\x94\x82 8398134 \xe2\x94\x82\n\xe2\x94\x94\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x98\n
Run Code Online (Sandbox Code Playgroud)\n
\n

熊猫

\n
sum(\n   len(pd.read_csv(file, sep=\'\\t\', quoting=3).index)\n   for file in files\n)\n
Run Code Online (Sandbox Code Playgroud)\n
CPU times: user 57.6 s, sys: 9.78 s, total: 1min 7s\nWall time: 1min 7s\n8398134\n
Run Code Online (Sandbox Code Playgroud)\n
\n

鸭数据库

\n
duckdb.sql("""\nfrom read_csv_auto(\'amazon-reviews/*.tsv\', sep=\'\\t\', quote=\'\')\nselect count(*)\n""").pl()\n
Run Code Online (Sandbox Code Playgroud)\n
CPU times: user 12.4 s, sys: 2.32 s, total: 14.7 s\nWall time: 5.05 s\nshape: (1, 1)\n\xe2\x94\x8c\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x90\n\xe2\x94\x82 count_star() \xe2\x94\x82\n\xe2\x94\x82 ---          \xe2\x94\x82\n\xe2\x94\x82 i64          \xe2\x94\x82\n\xe2\x95\x9e\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\xa1\n\xe2\x94\x82 8398134      \xe2\x94\x82\n\xe2\x94\x94\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x98\n
Run Code Online (Sandbox Code Playgroud)\n
\n

皮箭头

\n
parse_options = pyarrow.csv.ParseOptions(delimiter=\'\\t\', quote_char=False)\n\nsum(\n   pyarrow.csv.read_csv(file, parse_options=parse_options).num_rows\n   for file in files\n)\n
Run Code Online (Sandbox Code Playgroud)\n
CPU times: user 12.9 s, sys: 6.46 s, total: 19.4 s\nWall time: 6.65 s\n8398134\n
Run Code Online (Sandbox Code Playgroud)\n