如果总有成对的ID
您可以通过索引选择所有对行[1::2]
并除以移位值Series.shift http://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.Series.shift.html:
df['Result'] = df['Quantity'].iloc[1::2].div(df['Quantity'].shift())
print (df)
ID Quantity Time Result
0 54 100 2020-01-01 00:00:05 NaN
1 54 87 2020-01-01 00:00:06 0.870
2 58 400 2020-01-01 00:00:08 NaN
3 58 390 2020-01-01 00:00:14 0.975
与小组合作的解决方案:
另一个想法是使用GroupBy.transform http://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.core.groupby.GroupBy.transform.html with GroupBy.first http://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.core.groupby.GroupBy.first.html并除以最后一个值ID
by DataFrame.drop_duplicates http://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.DataFrame.drop_duplicates.html:
first = df.groupby('ID')['Quantity'].transform('first')
df['Result'] = df.drop_duplicates('ID', keep='last')['Quantity'].div(first)
print (df)
ID Quantity Time Result
0 54 100 2020-01-01 00:00:05 NaN
1 54 87 2020-01-01 00:00:06 0.870
2 58 400 2020-01-01 00:00:08 NaN
3 58 390 2020-01-01 00:00:14 0.975
或者使用 lambda 函数并替换为NaN
by Series.mask http://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.Series.mask.html:
df['Result'] = (df.groupby('ID')['Quantity'].transform(lambda x: x.iat[-1] / x.iat[0])
.mask(df['ID'].duplicated(keep='last')))
print (df)
ID Quantity Time Result
0 54 100 2020-01-01 00:00:05 NaN
1 54 87 2020-01-01 00:00:06 0.870
2 58 400 2020-01-01 00:00:08 NaN
3 58 390 2020-01-01 00:00:14 0.975
如果至少有一组具有独特的ID
?
print (df)
ID Quantity Time
0 54 100 2020-01-01 00:00:05
1 58 400 2020-01-01 00:00:08
2 58 390 2020-01-01 00:00:14
#failed
df['Result1'] = df['Quantity'].iloc[1::2].div(df['Quantity'].shift())
#working correct
first = df.groupby('ID')['Quantity'].transform('first')
df['Result2'] = df.drop_duplicates('ID', keep='last')['Quantity'].div(first)
#working correct
df['Result3'] = (df.groupby('ID')['Quantity'].transform(lambda x: x.iat[-1] / x.iat[0])
.mask(df['ID'].duplicated(keep='last')))
print (df)
ID Quantity Time Result1 Result2 Result3
0 54 100 2020-01-01 00:00:05 NaN 1.000 1.000
1 58 400 2020-01-01 00:00:08 4.0 NaN NaN
2 58 390 2020-01-01 00:00:14 NaN 0.975 0.975