我真的很喜欢pandas.assign()
函数,尤其是与lambda
表达式结合使用。
但是,在处理我不了解的字符串连接时,遇到了未知的行为。我已经找到了这个线程,但是它不能回答我的问题:
String concatenation of two pandas columns
我的问题的最小工作示例:
import pandas as pd
df = pd.DataFrame({'Firstname': ['Sandy', 'Peter', 'Dolly'],
'Surname': ['Sunshine', 'Parker', 'Dumb']})
返回
Firstname Surname
0 Sandy Sunshine
1 Peter Parker
2 Dolly Dumb
现在,如果我想分配例如Full Name
我以为我可以做到:
df = df.assign(**{'Full Name': lambda x: f'{x.Firstname} {x.Surname}'})
但这不仅会像预期的那样基于每个行创建一个新字符串,如“ Sandy Sunshine”,而且还会像这样在所有行上创建>
谁能解释我为什么我的方法不起作用以及为什么这样
df = df.assign(**{'Full Name': lambda x: x.Firstname + ' ' + x.Surname})
显然有效吗?谢谢:)
答案 0 :(得分:3)
df.assign(**{'Full Name': lambda x: f'{x.Firstname} {x.Surname}'})
那是你做错了的地方。
f-strings
将{}
中处理的内容保留到字符串中。
示例:
print(f"Hello {df} world")
hello 0 Sandy
1 Peter
2 Dolly
Name: Firstname, dtype: object world
因此,f'{x.Firstname} {x.Surname}'
的输出为
0 Sandy
1 Peter
2 Dolly
Name: Firstname, dtype: object 0 Sunshine
1 Parker
2 Dumb
Name: Surname, dtype: object
现在df.assign(new_col = 'a')
将输出:
Firstname Surname new_col
0 Sandy Sunshine a
1 Peter Parker a
2 Dolly Dumb a
这就是为什么每一行都有以下字符串的原因。
0 Sandy
1 Peter
2 Dolly
Name: Firstname, dtype: object 0 Sunshine
1 Parker
2 Dumb
Name: Surname, dtype: object
第二种情况:
df.assign(**{'Full Name': lambda x: x.Firstname + ' ' + x.Surname})
等同于
df.assign(Full_name = df['Firstname'] + ' ' + df['Surname']
它只是按元素进行字符串连接,因此可以按预期工作。
您可以在此处使用pd.Series.str.cat
。
df['Full Name'] = df['Firstname'].str.cat(df['Surname'],sep=' ')
答案 1 :(得分:1)
在熊猫f-string
中,元素用于组合字符串,因为不存在针对数组实现的解决方案。
因此,在您的解决方案中将所有Series
(df列)合并在一起。
如果需要使用f-string
,一种可能的解决方案是在压缩列中循环处理,分别处理每对:
df = df.assign(**{'Full Name': lambda x: [f'{Firstname} {Surname}'
for Firstname, Surname in
zip(x['Firstname'], x['Surname'])]})
print (df)
Firstname Surname Full Name
0 Sandy Sunshine Sandy Sunshine
1 Peter Parker Peter Parker
2 Dolly Dumb Dolly Dumb
答案 2 :(得分:1)
的结果
f'{df.Firstname} {df.Surname}'
具有str
类型,是熊猫系列的字符串表示形式,而
df.Firstname + ' ' + df.Surname
是pandas.core.series.Series
。因此,对分配的处理方式有所不同。