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分钟以上)是的,这不是最有效的方法。