pandas-groupby - Pandas 对按另一列分组的行求和
问题描述
我附上了数据集
Time podId Batt (avg) Temp (avg)
0 2019-10-07 9999 6.1 71.271053
1 2019-10-08 9999 6.0 71.208285
2 2019-10-09 9999 5.9 77.896628
3 2019-10-10 9999 5.8 78.709279
4 2019-10-11 9999 5.7 71.849283
59 2019-12-05 8888 5.5 76.548780
60 2019-12-06 8888 5.4 73.975295
61 2019-12-07 8888 5.3 76.209434
62 2019-12-08 8888 5.2 76.717481
63 2019-12-09 8888 5.1 70.433920
我使用 -batt2 = pd.read_csv('battV2.csv')
- 我需要确定何时发生电池更换,即
Batt (avg)
从前一行增加的时间。我可以通过以这种方式使用“差异”来做到这一点batt2['Vdiff']=batt2['Batt (avg)'].diff(-1)
- 现在对于每个
podId
我需要对Vdiff
电池变化之间的列求和,即在两个负值Vdiff
之间 - 我也需要
Temp (avg)
在相同的范围内进行平均 - 计数
Time
以确定电池更换之间的天数
谢谢。
解决方案
涉及几个步骤:
导入数据
请注意,我已经稍微更改了您的数据集,以便为您的需求提供有效的测试用例(在您给定的数据集中,Batt_avg
永远不会增加)。
from io import StringIO
import pandas as pd
data = StringIO('''Time podId Batt_avg Temp_avg
0 2019-10-07 9999 6.1 71.271053
1 2019-10-08 9999 6.0 71.208285
2 2019-10-09 9999 5.9 77.896628
3 2019-10-10 9999 5.8 78.709279
4 2019-10-11 9999 5.7 71.849283
5 2019-10-12 9999 6.0 71.208285
6 2019-10-13 9999 5.9 77.896628
7 2019-10-14 9999 5.8 78.709279
8 2019-10-15 9999 5.7 71.849283
59 2019-12-05 8888 5.5 76.548780
60 2019-12-06 8888 5.4 73.975295
61 2019-12-07 8888 5.3 76.209434
62 2019-12-08 8888 5.2 76.717481
63 2019-12-09 8888 5.1 70.433920''')
df = pd.read_csv(data, delim_whitespace=True)
确定电池电压的变化
正如您已经发现的那样,您可以使用diff()
. 我不确定您给出的代码是否df.Batt_avg.diff(-1)
满足您的要求:“即当 Batt (avg) 从上一行增加时”。相反,对于给定的行,这显示了下一行中的值将如何变化(乘以 -1)。如果您需要对上一行进行负面更改,则可以改用-df.Batt_avg.diff()
.
df['Batt_avg_diff'] = df.Batt_avg.diff(-1)
分组数据并应用聚合函数
您可以将分组条件表示df.podId.diff().fillna(0.0) != 0
为 podId 和“电池更换之间,即两个负 Vdiff 值之间”df.Batt_avg_diff.fillna(0.0) < 0
的条件- 其中任何一个都将触发一个新组。在触发器上使用以创建组。然后,您可以使用对这些组采取行动并将结果扩展到原始数据框的维度。cumsum()
groupby()
transform()
df['group'] = ((df.podId.diff().fillna(0.0) != 0) | (df.Batt_avg_diff.fillna(0.0) < 0)).cumsum()
df['Batt_avg_diff_sum'] = df.Batt_avg_diff.groupby(df.group).transform('sum')
df['Temp_avg_mean'] = df.Temp_avg.groupby(df.group).transform('mean')
日期时间计算
对于最后一步,您需要首先将字符串转换为日期时间以允许日期操作。然后您可以使用 groupby 操作来获取每个组中的最大值和最小值,并获取增量。
df.Time = pd.to_datetime(df.Time)
df['Time_days'] = df.Time.groupby(df.group).transform('max') - df.Time.groupby(df.group).transform('min')
注意:如果您不需要或不想要原始数据框中的聚合数据,只需直接应用函数(无需转换):
df_group = pd.DataFrame()
df_group['Batt_avg_diff_sum'] = df.Batt_avg_diff.groupby(df.group).sum()
df_group['Temp_avg_mean'] = df.Temp_avg.groupby(df.group).mean()
df_group['Time_days'] = df.Time.groupby(df.group).max() - df.Time.groupby(df.group).min()
推荐阅读
- regex - Linux 中的正则表达式 [\s]*
- matlab - LTspice2Matlab 函数似乎在 Octave 中不起作用
- azure-web-app-service - Microsoft 标识导致 Azure Web 应用程序崩溃
- css - 如何更改 React-Bootstrap NavDropdown 菜单背景颜色?
- flutter - 使用gridview颤振使滑块可滚动
- regex - 正则表达式在第一个零之后只匹配零
- json - 使用 n 组拆分从 Jmeter 中的 json 提取器中提取的字符串
- python - 使用 sqlalchemy 对复杂结构进行排序
- ionic-framework - PayPal 信用卡 - 网络与原生 - 在 PopUp 与 Inline 中显示不同的字段
- arrays - 使用 bash 和 readarray 将输出读入数组