基于另一列和多索引创建Pandas减法列

8oomwypt  于 2023-02-02  发布在  其他
关注(0)|答案(3)|浏览(159)

我在这里问过一个非常相似的问题,不幸的是,玩具问题对我的情况来说太简单了。
我有一个数据框,其中包含两个不同条件下的主题和多个用于不同通道的值列。

d = {
     "subject": [1, 1, 2, 2, 3, 3], 
     "condition": ["on", "off", "on", "off", "on", "off"], 
     "channel": [1, 1, 1, 1, 1, 2]
     "value": [1, 2, 3, 5, 4, 6]
     }
df = pd.DataFrame(data=d)
df

| | 主语|条件|通道|价值|
| - ------|- ------|- ------|- ------|- ------|
| 无|1个|在|1个|1个|
| 1个|1个|关闭|1个|第二章|
| 第二章|第二章|在|1个|三个|
| 三个|第二章|关闭|1个|六个|
| 四个|三个|在|1个|四个|
| 五个|三个|关闭|第二章|六个|
我想获得新列,指示两种条件 * 之间的差异 * 关-开 *,每个通道 *。如果一个条件中缺少一个通道,我想获得nan。在这种情况下,我想获得:
| | 主语|条件|通道|价值|值_关-开|
| - ------|- ------|- ------|- ------|- ------|- ------|
| 无|1个|在|1个|1个|1个|
| 1个|1个|关闭|1个|第二章|1个|
| 第二章|第二章|在|1个|三个|三个|
| 三个|第二章|关闭|1个|六个|三个|
| 四个|三个|在|1个|四个|楠|
| 五个|三个|关闭|第二章|六个|楠|
我该怎么做最好?
我不得不尝试在这里扩展解决方案,然而,这会引发错误:
x一个一个一个一个x一个一个二个x
有什么办法?

fruv7luv

fruv7luv1#

使用MultiIndex.map修复现有解决方案

s = df.pivot(index=['subject', 'channel'], columns='condition', values='value').eval('off-on')
df['off-on'] = df.set_index(['subject', 'channel']).index.map(s)

或者,您可以使用merge

s = df.pivot(index=['subject', 'channel'], columns='condition', values='value').eval('off-on')
df.merge(s.reset_index(name='off-on'))

结果

subject condition  channel  value  off-on
0        1        on        1      1     1.0
1        1       off        1      2     1.0
2        2        on        1      3     3.0
3        2       off        1      6     3.0
4        3        on        1      4     NaN
5        3       off        2      6     NaN
nfs0ujit

nfs0ujit2#

您可以使用:

df['value_off-on'] = (df.groupby(['subject', 'channel'])['value']
                        .transform(lambda x: x.diff().iloc[-1]))
print(df)

# Output
   subject condition  channel  value  value_off-on
0        1        on        1      1           1.0
1        1       off        1      2           1.0
2        2        on        1      3           3.0
3        2       off        1      6           3.0
4        3        on        1      4           NaN
5        3       off        2      6           NaN

注意:如果 Dataframe 尚未按condition排序,则必须先按df.sort_values('condition', ascending=False).groupby(...)排序

rmbxnbpk

rmbxnbpk3#

修改my previous answer以使用多列:

s = df.set_index(['condition', 'subject', 'channel'])['value']

# instead of map, use a merge
df['off-on'] = (df[['subject', 'channel']]
                .merge(s['off'].sub(s['on']).reset_index(), how='left')
               )['value']

# or indexing
df['off-on'] = df.set_index(['subject', 'channel']).index.map(s['off'].sub(s['on']))

输出:

subject condition  channel  value  off-on
0        1        on        1      1     1.0
1        1       off        1      2     1.0
2        2        on        1      3     2.0
3        2       off        1      5     2.0
4        3        on        1      4     NaN
5        3       off        2      6     NaN

相关问题