Python—根据条件向包含另一行值的数据帧添加列
我的数据框如下所示:Python—根据条件向包含另一行值的数据帧添加列,python,pandas,dataframe,Python,Pandas,Dataframe,我的数据框如下所示: +-----+-------+----------+-------+ | No | Group | refGroup | Value | +-----+-------+----------+-------+ | 123 | A1 | A1 | 5.0 | | 123 | B1 | A1 | 7.3 | | 123 | B2 | A1 | 8.9 | | 123 | B3 | B1 |
+-----+-------+----------+-------+
| No | Group | refGroup | Value |
+-----+-------+----------+-------+
| 123 | A1 | A1 | 5.0 |
| 123 | B1 | A1 | 7.3 |
| 123 | B2 | A1 | 8.9 |
| 123 | B3 | B1 | 7.9 |
| 465 | A1 | A1 | 1.4 |
| 465 | B1 | A1 | 4.5 |
| 465 | B2 | B1 | 7.3 |
+-----+-------+----------+-------+
现在我需要添加另一列,该列包含当前行中列value
的值与具有相同编号(No
)的行中列value
的值和写入refGroup
中的组(group
)的值之间的差值
示例:如果refGroup
等于Group
,值与refValue
相同
因此,结果应该是:
+-----+-------+----------+-------+----------+
| No | Group | refGroup | Value | refValue |
+-----+-------+----------+-------+----------+
| 123 | A1 | A1 | 5.0 | 5.0 |
| 123 | B1 | A1 | 7.3 | 2.3 |
| 123 | B2 | A1 | 8.9 | 3.9 |
| 123 | B3 | B1 | 7.9 | 0.6 |
| 465 | A1 | A1 | 1.4 | 1.4 |
| 465 | B1 | A1 | 4.5 | 3.1 |
| 465 | B2 | B1 | 7.3 | 2.8 |
+-----+-------+----------+-------+----------+
前两行的说明:
第一行:refGroup
等于Group
->refValue
=Value
第二行:搜索与Group
(A1)具有相同No
(123)和refGroup
的行,并计算当前行的值减去引用行的值(7.3-5.0=2.3)
我想我可能需要使用groupby()和apply(),但是如何使用呢
希望我的示例足够详细,如果您需要更多信息,请询问:)一种方法是使用类似数据库SQL的技术;将“自连接”与merge
一起使用。使用
上的left\u和
上的right\u将数据帧合并/连接到自身,将“Group”与“refGroup”对齐,然后从每个数据帧记录中减去值:
df_out = df.merge(df,
left_on=['No','refGroup'],
right_on=['No','Group'],
suffixes=('','_ref'))
df['refValue'] = np.where(df_out['Group'] == df_out['refGroup'],
df_out['value'],
df_out['value'] - df_out['value_ref'])
df
输出:
No Group refGroup value refValue
0 123 A1 A1 5.0 5.0
1 123 B1 A1 7.3 2.3
2 123 B2 A1 8.9 3.9
3 123 B3 B1 7.9 0.6
4 465 A1 A1 1.4 1.4
5 465 B1 A1 4.5 3.1
6 465 B2 B1 7.3 2.8
一种方法是使用类似SQL的数据库技术;将“自连接”与merge
一起使用。使用
上的left\u和
上的right\u将数据帧合并/连接到自身,将“Group”与“refGroup”对齐,然后从每个数据帧记录中减去值:
df_out = df.merge(df,
left_on=['No','refGroup'],
right_on=['No','Group'],
suffixes=('','_ref'))
df['refValue'] = np.where(df_out['Group'] == df_out['refGroup'],
df_out['value'],
df_out['value'] - df_out['value_ref'])
df
输出:
No Group refGroup value refValue
0 123 A1 A1 5.0 5.0
1 123 B1 A1 7.3 2.3
2 123 B2 A1 8.9 3.9
3 123 B3 B1 7.9 0.6
4 465 A1 A1 1.4 1.4
5 465 B1 A1 4.5 3.1
6 465 B2 B1 7.3 2.8
使用理解列表,您可以执行以下操作:
df['refValue'] = [ row['Value'] - float(df.loc[(df['No']==row['No']) & (df['Group']==row['refGroup']),'Value'].values) if row['refGroup']!=row['Group'] else row['Value'] for index, row in df.iterrows() ]
使用理解列表,您可以执行以下操作:
df['refValue'] = [ row['Value'] - float(df.loc[(df['No']==row['No']) & (df['Group']==row['refGroup']),'Value'].values) if row['refGroup']!=row['Group'] else row['Value'] for index, row in df.iterrows() ]
你可以使用和,试着找出你得到的输出或错误,然后发布或编辑你的问题吗?@MaMo你能描述一下0.6
的结果吗。我知道你用的是7.9-7.3
,但我想知道为什么你用7.3
,因为B1
不等于A1
你用的怎么样,试着找出你得到的输出或错误,然后发布或编辑你的问题?@MaMo你能描述一下0.6
的结果吗。我知道你用的是7.9-7.3
,但我想知道你为什么用7.3
,因为B1
不等于A1
太神奇了!我的数据帧很大,但此解决方案只需约一秒钟,谢谢!:)太神了我的数据帧很大,但此解决方案只需约一秒钟,谢谢!:)您的解决方案工作正常,但运行时间高度依赖于数据帧的大小(对于包含约60.000行的数据帧,需要超过10分钟)。是的,这不是最有效的方法。您的解决方案工作正常,但运行时间高度依赖于数据帧的大小(我的数据帧大约有60.000行,需要10分钟以上)是的,这不是最有效的方法。