Python 熊猫如何组合具有复杂规则/条件的组中的两行
我有一个数据帧:Python 熊猫如何组合具有复杂规则/条件的组中的两行,python,pandas,dataframe,loops,group-by,Python,Pandas,Dataframe,Loops,Group By,我有一个数据帧: import pandas as pd df = pd.DataFrame({ "ID": ['company A', 'company A', 'company A', 'company B','company B', 'company B', 'company C', 'company C','company C','company C', 'company D', 'company D','company D'], 'Sender':
import pandas as pd
df = pd.DataFrame({
"ID": ['company A', 'company A', 'company A', 'company B','company B', 'company B', 'company C', 'company C','company C','company C', 'company D', 'company D','company D'],
'Sender': [28, 'remove1', 'flag_source', 56, 28, 312, 'remove2', 'flag_source', 78, 102, 26, 101, 96],
'Receiver': [129, 28, 'remove1', 172, 56, 28, 61, 'remove2', 12, 78, 98, 26, 101],
'Date': ['2020-04-12', '2020-03-20', '2020-03-20', '2019-02-11', '2019-01-31', '2018-04-02', '2020-06-29', '2020-06-29', '2019-11-29', '2019-10-01', '2020-04-03', '2020-01-30', '2019-10-18'],
'Sender_type': ['house', 'temp', 'house', 'house', 'house', 'house', 'temp', 'house', 'house','house','house', 'temp', 'house'],
'Receiver_type': ['house', 'house', 'temp', 'house','house','house','house', 'temp', 'house','house','house','house','temp'],
'Price': [32, 50, 47, 21, 23, 19, 52, 39, 12, 22, 61, 53, 19]
})
df如下所示:
ID Sender Receiver Date Sender_type Receiver_type Price
0 company A 28 129 2020-04-12 house house 32
1 company A remove1 28 2020-03-20 temp house 50 # combine this row with below
2 company A flag_source remove1 2020-03-20 house temp 47 # combine this row with above
3 company B 56 172 2019-02-11 house house 21
4 company B 28 56 2019-01-31 house house 23
5 company B 312 28 2018-04-02 house house 19
6 company C remove2 61 2020-06-29 temp house 52 # combine this row and below
7 company C flag_source remove2 2020-06-29 house temp 39 # combine this row with above
8 company C 78 12 2019-11-29 house house 12
9 company C 102 78 2019-10-01 house house 22
10 company D 26 98 2020-04-03 house house 61
11 company D 101 26 2020-01-30 temp house 53
12 company D 96 101 2019-10-18 house temp 19
我希望按照以下规则合并/合并每个组“ID”(公司x)的两行:将“发件人”中包含“标志源”的行及其上面的行合并为一个新行。在这一新行中:发送方是标志源,“RevReceiver”是其上面的值(删除两个“删除”值),日期是上面的日期,发送方和接收方类型是“house”,而“Price”是前面的上面的值。然后拆下两行。例如,对于公司A,它将合并第1行和第2行以生成下面的新行:
ID Sender Receiver Date Sender_type Receiver_type Price
company A flag_source 28 2020-03-20 house house 50
然后使用此行替换前两行。其他组的规则相同(在这种情况下,仅适用于公司A和C)。最后,我希望有这样一个结果:
ID Sender Receiver Date Sender_type Receiver_type Price
0 company A 28 129 2020-04-12 house house 32
1 company A flag_source 28 2020-03-20 house house 50 # new row
2 company B 56 172 2019-02-11 house house 21
3 company B 28 56 2019-01-31 house house 23
4 company B 312 28 2018-04-02 house house 19
5 company C flag_source 61 2020-06-29 house house 52 # new row
6 company C 78 12 2019-11-29 house house 12
7 company C 102 78 2019-10-01 house house 22
8 company D 26 98 2020-04-03 house house 61
9 company D 101 26 2020-01-30 temp house 53
10 company D 96 101 2019-10-18 house temp 19
希望我对这个问题的解释是清楚的
由于这是一个简单的示例,实际案例中有许多类似的数据,我编写了一个循环,但速度非常慢,效率低下,因此如果您有任何想法和有效的方法,请提供帮助。非常感谢你的帮助 我相信以下方法是有效的:
mask = df.Sender == 'flag_source'
df[mask] = df.shift()
df.loc[mask, 'Sender'] = 'flag_source'
df.loc[mask, ['Sender_type','Receiver_type']] = 'house'
df = df[~mask.shift(-1).fillna(False).astype(bool)].reset_index(drop=True)
因此,步骤如下(按行):
- 为需要更改的行制作一个掩码
- 使用“shift”将这些行设置为上一行
- 将这些行的
重写为Sender
flag\u source
- 同时重写
和Sender\u type
Receiver\u type
- 在遮罩上再次使用
,删除前面的行。这似乎有点复杂;您还可以对不包含字符串的行执行类似于shift
的操作loc
remove
ID Sender Receiver Date Sender_type Receiver_type Price
0 company A 28 129 2020-04-12 house house 32.0
1 company A flag_source 28 2020-03-20 house house 50.0
2 company B 56 172 2019-02-11 house house 21.0
3 company B 28 56 2019-01-31 house house 23.0
4 company B 312 28 2018-04-02 house house 19.0
5 company C flag_source 61 2020-06-29 house house 52.0
6 company C 78 12 2019-11-29 house house 12.0
7 company C 102 78 2019-10-01 house house 22.0
8 company D 26 98 2020-04-03 house house 61.0
9 company D 101 26 2020-01-30 temp house 53.0
10 company D 96 101 2019-10-18 house temp 19.0
谢谢@Tom,我只是想知道为什么我们要做“df[mask]=df.shift()”@XaviorL
shift()
方法相对于索引“移动”数据。在这种情况下,每行下移1。因此,在df.shift()
中,要删除的行被移动到标志\u source
行的位置。通过使用df[mask]
,我们访问flag\u source
行,并用移位的数据重写它们。总之,我们将删除行复制到df
中的后续行。参见shift
文档: