gpt4 book ai didi

pandas - 有效地从 pandas DataFrame 中提取行,忽略丢失的索引标签

转载 作者:行者123 更新时间:2023-12-02 09:45:10 25 4
gpt4 key购买 nike

我正在寻找更有效的等价物

df.reindex(labels).dropna(subset=[0])

这可以避免在结果中包含缺少标签的 NaN 行,而不必在 reindex 之后删除它们将它们放入。

同样,我正在寻找一个高效的版本

df.loc[labels]

默默地忽略不在 df.index 中的标签,即结果的行数可能少于 labels 的元素.

当行、列和标签的数量都很大并且丢失率很高时,我需要一些高效的东西。具体来说,我正在寻找数据集长度中的次线性内容。

<小时/>

更新 1

这是 @MaxU 的回答之后问题的具体演示:

In [2]: L = 10**7
...: M = 10**4
...: N = 10**9
...: np.random.seed([3, 1415])
...: df = pd.DataFrame(np.random.rand(L, 2))
...: labels = np.random.randint(N, size=M)
...: M-len(set(labels))
...:
...:
Out[2]: 0

In [3]: %timeit df[df.index.isin(set(labels))]
904 ms ± 59.6 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)

In [4]: %timeit df.loc[df.index.intersection(set(labels))]
207 ms ± 11.4 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)

In [5]: %timeit df.loc[np.intersect1d(df.index, labels)]
427 ms ± 37 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)

In [6]: %timeit df.loc[labels[labels<L]]
329 µs ± 23 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)

In [7]: %timeit df.iloc[labels[labels<L]]
161 µs ± 8.35 µs per loop (mean ± std. dev. of 7 runs, 10000 loops each)

最后 2 个示例比迭代 df.index 的示例快约 1000 倍。这表明df.loc[labels]不会迭代索引,并且数据帧具有高效的索引结构,即 df.index确实索引。

所以问题是我如何获得像df.loc[labels[labels<L]]一样高效的东西当df.index不是连续的数字序列。部分解决方案是原始的

In [8]: %timeit df.reindex(labels).dropna(subset=[0])
1.81 ms ± 187 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)

这仍然比建议的解决方案快约 100 倍,但仍然比可能的解决方案损失了一个数量级。

<小时/>

更新2

为了进一步证明即使没有对索引的假设也可以获得次线性性能,请使用字符串索引重复上述内容

In [16]: df.index=df.index.map(str)
...: labels = np.array(list(map(str, labels)))
...:
...:

In [17]: %timeit df[df.index.isin(set(labels))]
657 ms ± 48.7 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)

In [18]: %timeit df.loc[df.index.intersection(set(labels))]
974 ms ± 160 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)

In [19]: %timeit df.reindex(labels).dropna()
8.7 ms ± 121 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)

所以要明确的是,我正在寻找比 df.reindex(labels).dropna() 更有效的东西。 。这在 df.shape[0] 中已经是次线性的了。并且不对索引做出任何假设,因此解决方案也应该如此。

我想解决的问题是df.reindex(labels)将包括NaN缺少标签的行需要使用 dropna 删除。我正在寻找相当于 df.reindex(labels) 的值这不会首先将它们放在那里,而不扫描整个 df.index找出丢失的标签。至少在原则上这必须是可能的:如果 reindex可以通过插入虚拟行来有效地动态处理丢失的标签,应该可以通过不执行任何操作来更有效地动态处理它们。

最佳答案

这是不同方法的一个小比较。

样本 DF(形状:10.000.000 x 2):

np.random.seed([3, 1415])
df = pd.DataFrame(np.random.rand(10**7, 2))
labels = np.random.randint(10**9, size=10**4)

In [88]: df.shape
Out[88]: (10000000, 2)

有效(现有标签):

In [89]: (labels <= 10**7).sum()
Out[89]: 1008

无效(不存在标签):

In [90]: (labels > 10**7).sum()
Out[90]: 98992

时间:

In [103]: %timeit df[df.index.isin(set(labels))]
943 ms ± 7.86 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)

In [104]: %timeit df.loc[df.index.intersection(set(labels))]
360 ms ± 1.65 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)

In [105]: %timeit df.loc[np.intersect1d(df.index, labels)]
513 ms ± 655 µs per loop (mean ± std. dev. of 7 runs, 1 loop each)

关于pandas - 有效地从 pandas DataFrame 中提取行,忽略丢失的索引标签,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49830069/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com