我有一个非常巨大的 DataFrame,其中包含数百万行和大约 20-30 列,其中包含各种类型的数据,例如。字符串、数字、日期等
df
index t1 num1 float1 ... str2
0 2014-10-21 3456 0.000 ... ayzkcxtoScUy
1 2014-10-21 2453 0.000 ... jZygJWtxyVnS
... ... ... ... ... ...
n-1 2020-11-06 708735 670.818 ... UWVhmKCfmzVj
n 2020-11-06 70630 670.817 ... EvhreYZotqVS
让我们说它很疯狂,但我需要每一行都有它的所有值。我现在想对某些列进行分组,并df根据组大小从原始 DataFrame 中消除组和行。特别是,我想消除所有大小为 1 的组。
第一种天真的方法
我搜索并尝试使用这个答案:如何在 Pandas 数据框中选择值出现多次的行
lst = ["t1", "str1", "num1", "str2", "num2"]
df = df.groupby(lst).filter(lambda x: len(x.index) > 1).reset_index(drop=True)
这确实按预期工作。我的 DataFramedf现在从大小为 1 的组中出现的所有行中过滤。问题是使用 filter 方法与我的 DataFrame 的尺寸相关的时间,这需要太长时间。从这个角度来看,对这些样本列进行分组将产生大约 165,000 个组和 250 万行 DataFrame,其中大约三分之一的组的大小为 1。我不得不中止这个脚本的执行,因为它需要年龄。我进一步尝试使用来自此链接的灵感如何提高熊猫 GroupBy 过滤器操作的性能?但无法使用它map,因为我在 DataFrame 上而不是在 Series 上进行分组。使用该transform方法,性能恶化。
边注
进一步调查,我发现在具有和/或列filter的 DataFrame 上使用时出现了问题。我曾经删除所有这三个列,这将过滤方法的性能提高了大约三分之一。仍然不够,但足以在这里提及它,尤其是当我需要这些列并且不能只删除它们时。datetime64[ns, UTC]datetime64[ns]Del df[x]
第二种“聪明”的方法
然后,我尝试通过使用.value_counts()from link 1巧妙地对我的数据进行索引来规避 groupby、过滤或转换的使用。
vc = df[lst].value_counts()
vc_index = vc.index[vc.gt(1)]
df = data[data[lst].isin(vc_index)]
我正在获取值计数vc以定位计数为 1 的所有索引,然后创建一个new_index仅包含所需索引(即count > 1)的 MultiIndex。之后,我尝试在链接1df中使用like 过滤我,它将所有值设置为 NaN/NaT。我被困在这里 - 我不确定我在这里做错了什么。.isin()df
df
index t1 num1 float1 ... str2
0 NaT NaN NaN ... NaN
1 NaT NaN NaN ... NaN
... ... ... ... ... ...
n-1 NaT NaN NaN ... NaN
n NaT NaN NaN ... NaN
在另一次尝试中,我尝试使用该pd.index.difference()方法
vc = data[lst].value_counts()
df = data.set_index(keys=lst)
df.index = df.index.difference(other=vc.index[vc.gt(1)])
但这只给了我一个TypeError: '<' not supported between instances of 'float' and 'str'.
老实说,我有点不知道什么是最好的,因为两天以来一直坐在这个问题上。我什至考虑过并行化(也许使用 Dask?),但我不确定如何使用它,因为我从未使用过它。帮助将不胜感激。