如果 Pandas 列不包含同一行中另一列的值,则将另一列的值添加到新行中
If a Pandas column doesn't contain a value from another column in the same row, then add the value from another column in a new line
我想在新行中将“A”列中的值添加到“B”列中,前提是“A”列中的相应值不包含在“B”列中。
我的数据框:
df
A B
value1 value4
value1
value1 value4\nvalue1\n
value2 value4\nvalue7\n
value2 value4\n
value3
value3 value4\nvalue3\nvalue6
value3 value2\nvalue1
value3 value3\nvalue1\nvalue6
所以,我想要的数据框
df
A B
value1 value4\nvalue1
value1 value1
value1 value4\nvalue1
value2 value4\nvalue7\nvalue2
value2 value4\nvalue2
value3 value3
value3 value4\nvalue3\nvalue6
value3 value2\nvalue1\nvalue3
value3 value3\nvalue1\nvalue6
此外,问题是有时在“B”列中的字符串末尾会出现 \n,有时则不会。
我尝试使用 df.A.str.contains(df["A"])
,但是当 contains()
有一个数据框列时它不起作用。我认为这样的方法可行:df.B.str.extract('(%s)' % '|'.join(df.A))
,这仅适用于“B”列中存在的“A”列中的值 - 对于匹配项,我不知道如何适应我的问题。
创建一个具有列表推导式的布尔掩码。用空字符串替换缺失值并使用 Series.where
:
mask = [a in b for a, b in zip(df['A'], df['B'].fillna(''))]
b = df['B'].str.replace(r'\n$', '')
df['B'] = b.where(mask, b + '\n' + df['A']).fillna(df['A'])
print (df)
A B
0 value1 value4\nvalue1
1 value1 value1
2 value1 value4\nvalue1
3 value2 value4\nvalue7\nvalue2
4 value2 value4\nvalue2
5 value3 value3
6 value3 value4\nvalue3\nvalue6
7 value3 value2\nvalue1\nvalue3
8 value3 value3\nvalue1\nvalue6
我建议您为此目的使用 df.apply
。在里面,您将能够使用 lambda
来创建您的条件。同样,我使用 strip()
从开头和结尾删除 \n
。请看下面的代码:
# Code to build the dataframe
import pandas as pd
d = {'A': ['value1', 'value1', 'value1', 'value2', 'value2', 'value3', 'value3', 'value3', 'value3'], 'B': ['value4', '', 'value4\nvalue1\n', 'value4\nvalue7\n', 'value4\n', '', 'value4\nvalue3\nvalue6', 'value2\nvalue1', 'value3\nvalue1\nvalue6']}
df = pd.DataFrame(data=d)
# Here is the code to use
print(df.apply(lambda x: [x["A"], (x["B"].strip()+"\n"+x["A"]).strip()] if x["A"] not in x["B"] else [x["A"], x["B"].strip()], axis=1, result_type='broadcast'))
输出:
A B
0 value1 value4\nvalue1
1 value1 value1
2 value1 value4\nvalue1
3 value2 value4\nvalue7\nvalue2
4 value2 value4\nvalue2
5 value3 value3
6 value3 value4\nvalue3\nvalue6
7 value3 value2\nvalue1\nvalue3
8 value3 value3\nvalue1\nvalue6
8 value3 value3\nvalue1\nvalue6
我想在新行中将“A”列中的值添加到“B”列中,前提是“A”列中的相应值不包含在“B”列中。
我的数据框:
df
A B
value1 value4
value1
value1 value4\nvalue1\n
value2 value4\nvalue7\n
value2 value4\n
value3
value3 value4\nvalue3\nvalue6
value3 value2\nvalue1
value3 value3\nvalue1\nvalue6
所以,我想要的数据框
df
A B
value1 value4\nvalue1
value1 value1
value1 value4\nvalue1
value2 value4\nvalue7\nvalue2
value2 value4\nvalue2
value3 value3
value3 value4\nvalue3\nvalue6
value3 value2\nvalue1\nvalue3
value3 value3\nvalue1\nvalue6
此外,问题是有时在“B”列中的字符串末尾会出现 \n,有时则不会。
我尝试使用 df.A.str.contains(df["A"])
,但是当 contains()
有一个数据框列时它不起作用。我认为这样的方法可行:df.B.str.extract('(%s)' % '|'.join(df.A))
,这仅适用于“B”列中存在的“A”列中的值 - 对于匹配项,我不知道如何适应我的问题。
创建一个具有列表推导式的布尔掩码。用空字符串替换缺失值并使用 Series.where
:
mask = [a in b for a, b in zip(df['A'], df['B'].fillna(''))]
b = df['B'].str.replace(r'\n$', '')
df['B'] = b.where(mask, b + '\n' + df['A']).fillna(df['A'])
print (df)
A B
0 value1 value4\nvalue1
1 value1 value1
2 value1 value4\nvalue1
3 value2 value4\nvalue7\nvalue2
4 value2 value4\nvalue2
5 value3 value3
6 value3 value4\nvalue3\nvalue6
7 value3 value2\nvalue1\nvalue3
8 value3 value3\nvalue1\nvalue6
我建议您为此目的使用 df.apply
。在里面,您将能够使用 lambda
来创建您的条件。同样,我使用 strip()
从开头和结尾删除 \n
。请看下面的代码:
# Code to build the dataframe
import pandas as pd
d = {'A': ['value1', 'value1', 'value1', 'value2', 'value2', 'value3', 'value3', 'value3', 'value3'], 'B': ['value4', '', 'value4\nvalue1\n', 'value4\nvalue7\n', 'value4\n', '', 'value4\nvalue3\nvalue6', 'value2\nvalue1', 'value3\nvalue1\nvalue6']}
df = pd.DataFrame(data=d)
# Here is the code to use
print(df.apply(lambda x: [x["A"], (x["B"].strip()+"\n"+x["A"]).strip()] if x["A"] not in x["B"] else [x["A"], x["B"].strip()], axis=1, result_type='broadcast'))
输出:
A B
0 value1 value4\nvalue1
1 value1 value1
2 value1 value4\nvalue1
3 value2 value4\nvalue7\nvalue2
4 value2 value4\nvalue2
5 value3 value3
6 value3 value4\nvalue3\nvalue6
7 value3 value2\nvalue1\nvalue3
8 value3 value3\nvalue1\nvalue6
8 value3 value3\nvalue1\nvalue6