我有一个DataFrame,有key列和value列.value有时是NA:

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列求和.如果任何valuekey的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?

推荐答案

一种解决方法是将NAN替换为inf,这将在聚合后生成NAN:

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

更快的替代方案:

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

输出示例:

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相关问答推荐

使用from_pandas将GeDataFrame转换为polars失败,ArrowType错误:未传递numpy. dype对象

Python Hashicorp Vault库hvac创建新的秘密版本,但从先前版本中删除了密钥

在Pandas 日历中插入一行

如何根据另一列值用字典中的值替换列值

从收件箱中的列中删除html格式

通过Selenium从页面获取所有H2元素

从groupby执行计算后创建新的子框架

Godot:需要碰撞的对象的AdditionerBody2D或Area2D以及queue_free?

avxspan与pandas period_range

所有列的滚动标准差,忽略NaN

pandas在第1列的id,第2列的标题,第3列的值,第3列的值?

调用decorator返回原始函数的输出

Plotly Dash Creating Interactive Graph下拉列表

Python Tkinter为特定样式调整所有ttkbootstrap或ttk Button填充的大小,适用于所有主题

Flash只从html表单中获取一个值

如何用FFT确定频变幅值

Python日志(log)库如何有效地获取lineno和funcName?

仅取消堆叠最后三列

如何从一个维基页面中抓取和存储多个表格?

VSCode Pylance假阳性(?)对ImportError的react