python - 在处理 NaN 时如何快速对 Pandas groupby 对象求和?

标签 python pandas performance group-by

我有一个带有 keyvalue 列的 DataFrame有时不适用:

df = pd.DataFrame({
    'key': np.random.randint(0, 1_000_000, 100_000_000),
    'value': np.random.randint(0, 1_000, 100_000_000).astype(float),
})
    
df.loc[df.value == 0, 'value'] = np.nan

我想按key 进行分组,并对value 列求和。如果的任何为NA,我希望总和为NA。

this answer中的代码在我的机器上需要 35.7 秒:

df.groupby('key')['value'].apply(np.array).apply(np.sum)

这比理论上可能的速度要慢得多。内置的 Pandas SeriesGroupBy.sum 在我的机器上需要 6.31 秒:

df.groupby('key')['value'].sum()

但它不支持 NA 处理(请参阅 this GitHub issue )。

我可以编写哪些代码来获得与内置运算符相当的性能,同时仍然处理 NaN?

最佳答案

一种解决方法可能是用 Inf 替换 NaN:

df.fillna({'value': np.inf}).groupby('key')['value'].sum().replace(np.inf, np.nan)

更快的替代方案:

df['value'].fillna(np.inf).groupby(df['key']).sum().replace(np.inf, np.nan)

示例输出:

key
0        45208.0
1            NaN
2        62754.0
3        50001.0
4        51073.0
          ...   
99995    55102.0
99996    43048.0
99997    49497.0
99998    43301.0
99999        NaN
Name: value, Length: 100000, dtype: float64

计时(10m 行)。

# original sum
743 ms ± 81 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)

# Inf workaround
918 ms ± 70.6 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)

# Inf workaround (alternative)
773 ms ± 60.6 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)

# custom apply with numpy
5.99 s ± 263 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)

关于python - 在处理 NaN 时如何快速对 Pandas groupby 对象求和?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/76947564/

相关文章:

python - 腐 eclipse 阵列的几层

python - 为 C++(指针)创建 swig 包装器到 python

python - 静态方法与类方法的类变量范围

python - 无法查看 Heroku 日志 - 无法读取未定义的属性 'run'

python - Pandas - Vlookup - 搜索列中的重复值

Python Pandas : DataFrame modification with diagnal value = 0

python - 使用Python解析JSON格式的日期

java - Android 通过名称以编程方式连接到 Open WiFi - 这是最佳解决方案?

python - 提高 Python 嵌套 for 循环的性能

C++ 独立数据的多线程性能