本文整理的技巧与之前整理的10个Pandas常用技巧不同。你可能不经常使用它,但有时当你遇到一些非常棘手的问题时,这些技巧有时可以帮助你快速解决一些不常见的问题。1.分类类型默认情况下,选项数量有限的列被分配对象类型。但就内存而言,这不是一个有效的选择。我们可以索引这些列并仅使用对对象的引用而不是实际值。Pandas提供了一个名为Categorical的Dtype来解决这个问题。例如,具有图像路径组成的大数据集。每行有三列:anchor、positive和negative。对分类列使用Categorical可以显着减少内存使用量。#原始数据+------------+--------------------+|类|文件名|+------------+------------------------+|Bathroom|Bathroom\bath_1.jpg||浴室|浴室\bath_100.jpg||浴室|浴室\bath_1003.jpg||浴室|浴室\bath_1004.jpg||浴室|浴室\bath_1005.jpg|+------------+------------------------+#目标+------------------------+------------------------+----------------------------+|锚|正|负|+------------------------+----------------------+--------------------------+|Bathroom\bath_1.jpg|Bathroom\bath_100.jpg|Dinning\din_540.jpg||浴室\bath_100.jpg|浴室\bath_1003.jpg|餐厅\din_1593.jpg||浴室\bath_1003.jpg|浴室\bath_1004.jpg|卧室\bed_329.jpg||浴室\bath_1004.jpg|浴室\bath_1005.jpg|客厅\living_1030.jpg||浴室\bath_1005.jpg|浴室\bath_1007.jpg|卧室\bed_1240.jPG|+------------------------+----------------------+------------------------+filename列的值经常会重复so,所以通过使用Categorical可以大大减少内存使用情况。让我们读取目标数据集并查看内存差异:triplets.info(memory_usage="deep")#ColumnNon-NullCountDtype#---------------------------#0anchor525000non-nullcategory#1positive525000non-nullcategory#2negative525000non-nullcategory#dtypes:category(3)#memoryusage:4.6MB#withoutcategoriestriplets_raw.info(memory_usage="deep")#ColumnNon-NullCountDtype#---------------------------#0anchor525000non-nullobject#1positive525000non-nullobject#2negative525000non-nullobject#dtypes:object(3)#memoryusage:118.1MB差异非常大,并且随着重复次数的增加,差异越来越大非-线性地。2.行列转换SQL经常会遇到行列转换的问题,而Pandas有时也需要。让我们看看来自Kaggle比赛的数据集。census_start.csv文件:如您所见,这些是按年份保存的。如果有year和pct_bb这列就更好了,每一行都有对应的值吧?cols=sorted([colforcolinoriginal_df.columns\ifcol.startswith("pct_bb")])df=original_df[(["cfips"]+cols)]df=df.melt(id_vars="cfips",value_vars=cols,var_name="year",value_name="feature").sort_values(by=["cfips","year"])看看结果,这样是不是好多了:3.apply()很慢,我们上次介绍了time但是,最好不要使用此方法,因为它会遍历每一行并调用指定的方法。但是如果我们别无选择,有没有办法提高速度呢?您可以使用swifter或pandarallew等包来并行化该过程。更快的importpandasaspdimportswifterdeftarget_function(row):returnrow*10deftraditional_way(data):data['out']=data['in'].apply(target_function)defswifter_way(data):data['out']=data['in'].swifter.apply(target_function)Pandarallelimportpandasaspdfrompandarallelimportpandaralleldeftarget_function(row):returnrow*10deftraditional_way(data):data['out']=data['in'].apply(target_function)defpandarallel_way(data):pandarallel.initialize()data['out']=data['in'].parallel_apply(target_function)通过多线程,可以提高计算速度,当然如果有集群,最好使用dask或者pyspark4,nullvalue,int,Int64标准整型数据类型不支持null值,所以会自动转为浮点数。所以如果你的数据需要整数字段中的空值,考虑使用Int64数据类型,因为它会使用pandas.NA来表示空值。5.CSV、压缩还是镶木地板?尽可能选择实木复合地板。Parquet会保留数据类型,读取数据时无需指定dtype。parquet文件默认经过snappy压缩,占用磁盘空间小。来看看几个对比|文件|尺码|+------------------------+--------+|三胞胎_525k.csv|38.4MB||triplets_525k.csv.gzip|4.3MB||triplets_525k.csv.zip|4.5MB||triplets_525k.parquet|1.9MB|+----------------------------+--------+读取镶木地板需要额外的包,如pyarrow或fastparquet。chatgpt说pyarrow比fastparquet快,但是我在小数据集上测试的时候fastparquet比pyarrow快,但是这里推荐使用pyarrow,因为pandas2.0默认也是用这个的。6.value_counts()计算相对频率,包括获取绝对值、计数和除以总数是复杂的,但是使用value_counts可以更轻松地完成这项任务,并且该方法提供了包含或排除空值的选项。df=pd.DataFrame({"a":[1,2,None],"b":[4.,5.1,14.02]})df["a"]=df["a"].astype("Int64")print(df.info())print(df["a"].value_counts(normalize=True,dropna=False),df["a"].value_counts(normalize=True,dropna=True),sep="\n\n")这样是不是简单多了?7.Modin注意:Modin还处于测试阶段。pandas是单线程的,但Modin可以通过缩放pandas来加快工作流程,它在pandas可能变得非常慢或内存密集型导致OOM的较大数据集上特别有效。!pipinstallmodin[all]importmodin.pandasaspddf=pd.read_csv("my_dataset.csv")下面是modin官网的架构图,有兴趣的研究一下:8.如果你经常遇到复杂的如果你有semi-结构化数据,需要单独列出来,可以用这个方法:importpandasaspdregex=(r'(?P
