熊猫汇总按另一列分组的行

时间:2020-03-26 04:47:54

标签: pandas-groupby

我已附加数据集

 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')

导入了它
  1. 我需要确定何时更换电池,即Batt (avg)从上一行开始增加的时间。我可以通过以这种方式使用'diff'batt2['Vdiff']=batt2['Batt (avg)'].diff(-1)
  2. 现在对于每个podId,我需要在两次电池更换之间(即两个负Vdiff负值之间)汇总Vdiff
  3. 我还需要在相同范围内平均Temp (avg)
  4. 计算Time,以确定两次电池更换之间的天数

谢谢。

1 个答案:

答案 0 :(得分:0)

涉及两个步骤:

导入数据

请注意,我对您的数据集做了一些更改,以便为您的需求提供有效的测试用例(在您给定的数据集中,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)

分组数据并应用聚合功能

对于podId,您可以将分组条件表示为df.podId.diff().fillna(0.0) != 0,对于条件“电池更换之间,即两个负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')

日期时间计算

对于最后一步,您需要首先将字符串转换为datetime以允许进行日期操作。然后,您可以使用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()