具有相同代码的行中的后续值之间的差异:值错误
Difference between subsequent values in rows with same code: value error
我有一个包含 3 列的 DataFrame:POD(代码)、时间戳、EAI_ALL(数字)。
我想计算第 4 列,其中每一行都具有以下值:当前行的 EAI_ALL 的值减去上一行的 EAI_ALL 的值。必须对每个代码执行此操作(例如,如果当前代码为 2 而前一行中的代码为 1,则计算值必须为 0,因为代码不同)。
我设法用以下代码完成了这个操作:
#group the DF by POD code
grouped = df.groupby('POD')
#Define Lambda function
eai_diff = lambda x: x.EAI_ALL - x.EAI_ALL.shift(+1)
df['EAI_Delta'] = grouped.apply(eai_diff).reset_index(0, drop=True).fillna(0)
这很好用,除非我在 DataFrame 中只有一个 POD 代码。
如果我将函数应用于只有一个 POD 代码的 DataFrame,我会不断收到此错误。
ValueError: Wrong number of items passed 48, placement implies 1
如您所见,df 有 48 行,但使用 group by 后它减少到一行。
我需要 groupby,因为如果我有多个 POD 代码,基本上必须一次对一个 POD 代码进行操作。
有人有什么建议吗?
提前致谢!
如果你使用低于1.1.0
的pandas版本你可以将groupby
的squeeze
参数设置为True
:
import pandas as pd
def group_with_squeeze(df):
grouped = df.groupby('POD', squeeze=True)
eai_diff = lambda x: x.EAI_ALL - x.EAI_ALL.shift(+1)
df['EAI_Delta'] = grouped.apply(eai_diff).reset_index(0, drop=True).fillna(0)
df = pd.DataFrame({'POD': list('ABBBCC'), 'EAI_ALL': [1, 2, 3, 1, 4, 4]})
group_with_squeeze(df)
df
# POD EAI_ALL EAI_Delta
# 0 A 1 0.0
# 1 B 2 0.0
# 2 B 3 1.0
# 3 B 1 -2.0
# 4 C 4 0.0
# 5 C 4 0.0
df = pd.DataFrame({'POD': list('AAAAAA'), 'EAI_ALL': [1, 2, 3, 1, 4, 4]})
group_with_squeeze(df)
df
# POD EAI_ALL EAI_Delta
# 0 A 1 0.0
# 1 A 2 1.0
# 2 A 3 1.0
# 3 A 1 -2.0
# 4 A 4 3.0
# 5 A 4 0.0
这是一个经常出现的错误,这是因为 return 从一个数据帧 apply
中使用一个组 return 一个数据帧中的一个系列 return行,索引作为列:
>>> df
POD EAI_ALL
0 foo 0
1 foo 1
2 foo 2
3 foo 3
4 foo 4
5 foo 5
6 foo 6
7 foo 7
8 foo 8
>>> df.groupby('POD').apply(lambda x: x.EAI_ALL - x.EAI_ALL.shift(+1))
EAI_ALL 0 1 2 3 4 5 6 7 8
POD
foo NaN 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0
为避免这种情况,如果您确实需要 .apply
,您可以 return 一个数据框:
>>> df.groupby('POD').apply(lambda x: x[['EAI_ALL']] - x[['EAI_ALL']].shift(+1))
EAI_ALL
0 NaN
1 1.0
2 1.0
3 1.0
4 1.0
5 1.0
6 1.0
7 1.0
8 1.0
然而,更好的方法是尽量远离 .apply
。对于您的用例,groupby.shift()
工作得很好,并且只会按照您的预期在组内移动:
>>> df.groupby('POD')['EAI_ALL'].shift()
0 NaN
1 0
2 1
3 2
4 3
5 4
6 5
>>> df['EAI_Delta'] = (df['EAI_ALL'] - df.groupby('POD')['EAI_ALL'].shift()).fillna(0)
>>> df
POD EAI_ALL EAI_Delta
0 foo 0 0.0
1 foo 1 1.0
2 foo 2 1.0
3 foo 3 1.0
4 foo 4 1.0
5 foo 5 1.0
6 foo 6 1.0
7 foo 7 1.0
8 foo 8 1.0
以及具有多个 POD
值的示例:
>>> df2['EAI_Delta'] = (df2['EAI_ALL'] - df2.groupby('POD')['EAI_ALL'].shift()).fillna(0)
>>> df2
POD EAI_ALL EAI_Delta
0 foo 0 0.0
1 foo 1 1.0
2 foo 2 1.0
3 foo 3 1.0
4 bar 4 0.0
5 bar 5 1.0
6 bar 6 1.0
7 bar 7 1.0
8 bar 8 1.0
如@mandiatodos 在评论中建议的更好,您可以直接使用 .groupby().diff()
我有一个包含 3 列的 DataFrame:POD(代码)、时间戳、EAI_ALL(数字)。 我想计算第 4 列,其中每一行都具有以下值:当前行的 EAI_ALL 的值减去上一行的 EAI_ALL 的值。必须对每个代码执行此操作(例如,如果当前代码为 2 而前一行中的代码为 1,则计算值必须为 0,因为代码不同)。 我设法用以下代码完成了这个操作:
#group the DF by POD code
grouped = df.groupby('POD')
#Define Lambda function
eai_diff = lambda x: x.EAI_ALL - x.EAI_ALL.shift(+1)
df['EAI_Delta'] = grouped.apply(eai_diff).reset_index(0, drop=True).fillna(0)
这很好用,除非我在 DataFrame 中只有一个 POD 代码。 如果我将函数应用于只有一个 POD 代码的 DataFrame,我会不断收到此错误。
ValueError: Wrong number of items passed 48, placement implies 1
如您所见,df 有 48 行,但使用 group by 后它减少到一行。 我需要 groupby,因为如果我有多个 POD 代码,基本上必须一次对一个 POD 代码进行操作。
有人有什么建议吗? 提前致谢!
如果你使用低于1.1.0
的pandas版本你可以将groupby
的squeeze
参数设置为True
:
import pandas as pd
def group_with_squeeze(df):
grouped = df.groupby('POD', squeeze=True)
eai_diff = lambda x: x.EAI_ALL - x.EAI_ALL.shift(+1)
df['EAI_Delta'] = grouped.apply(eai_diff).reset_index(0, drop=True).fillna(0)
df = pd.DataFrame({'POD': list('ABBBCC'), 'EAI_ALL': [1, 2, 3, 1, 4, 4]})
group_with_squeeze(df)
df
# POD EAI_ALL EAI_Delta
# 0 A 1 0.0
# 1 B 2 0.0
# 2 B 3 1.0
# 3 B 1 -2.0
# 4 C 4 0.0
# 5 C 4 0.0
df = pd.DataFrame({'POD': list('AAAAAA'), 'EAI_ALL': [1, 2, 3, 1, 4, 4]})
group_with_squeeze(df)
df
# POD EAI_ALL EAI_Delta
# 0 A 1 0.0
# 1 A 2 1.0
# 2 A 3 1.0
# 3 A 1 -2.0
# 4 A 4 3.0
# 5 A 4 0.0
这是一个经常出现的错误,这是因为 return 从一个数据帧 apply
中使用一个组 return 一个数据帧中的一个系列 return行,索引作为列:
>>> df
POD EAI_ALL
0 foo 0
1 foo 1
2 foo 2
3 foo 3
4 foo 4
5 foo 5
6 foo 6
7 foo 7
8 foo 8
>>> df.groupby('POD').apply(lambda x: x.EAI_ALL - x.EAI_ALL.shift(+1))
EAI_ALL 0 1 2 3 4 5 6 7 8
POD
foo NaN 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0
为避免这种情况,如果您确实需要 .apply
,您可以 return 一个数据框:
>>> df.groupby('POD').apply(lambda x: x[['EAI_ALL']] - x[['EAI_ALL']].shift(+1))
EAI_ALL
0 NaN
1 1.0
2 1.0
3 1.0
4 1.0
5 1.0
6 1.0
7 1.0
8 1.0
然而,更好的方法是尽量远离 .apply
。对于您的用例,groupby.shift()
工作得很好,并且只会按照您的预期在组内移动:
>>> df.groupby('POD')['EAI_ALL'].shift()
0 NaN
1 0
2 1
3 2
4 3
5 4
6 5
>>> df['EAI_Delta'] = (df['EAI_ALL'] - df.groupby('POD')['EAI_ALL'].shift()).fillna(0)
>>> df
POD EAI_ALL EAI_Delta
0 foo 0 0.0
1 foo 1 1.0
2 foo 2 1.0
3 foo 3 1.0
4 foo 4 1.0
5 foo 5 1.0
6 foo 6 1.0
7 foo 7 1.0
8 foo 8 1.0
以及具有多个 POD
值的示例:
>>> df2['EAI_Delta'] = (df2['EAI_ALL'] - df2.groupby('POD')['EAI_ALL'].shift()).fillna(0)
>>> df2
POD EAI_ALL EAI_Delta
0 foo 0 0.0
1 foo 1 1.0
2 foo 2 1.0
3 foo 3 1.0
4 bar 4 0.0
5 bar 5 1.0
6 bar 6 1.0
7 bar 7 1.0
8 bar 8 1.0
如@mandiatodos 在评论中建议的更好,您可以直接使用 .groupby().diff()