11_Pandas.DataFrame中组合多个列的字符串来创建新列
以下对pandas.DataFrame的多列字符串通过合并(串联)来创建新列的方法进行说明。
- 连接字符串
- str.cat()
- +运算符
- NaN缺失值的处理
- 字符串列和数值列的连接
- 将串联的列添加到pandas.DataFrame
以下面的数据为例。
import pandas as pd
df = pd.read_csv('./data/11/sample_pandas_normal.csv').head(3)
print(df)
# name age state point
# 0 Alice 24 NY 64
# 1 Bob 42 CA 92
# 2 Charlie 18 CA 70
连接字符串
str.cat()
可以使用字符串方法str.cat()连接字符串。
调用原pandas.Series和第一个参数中指定的pandas.Series的元素进行串联,返回一个pandas.Series。
print(df['name'].str.cat(df['state']))
# 0 AliceNY
# 1 BobCA
# 2 CharlieCA
# Name: name, dtype: object
如果为参数sep指定了字符串,则会在它们之间插入一个字符串。
print(df['name'].str.cat(df['state'], sep=' in '))
# 0 Alice in NY
# 1 Bob in CA
# 2 Charlie in CA
# Name: name, dtype: object
可以将具有相同数量元素的NumPy数组ndarray或list指定为第一个参数。
print(df['name'].str.cat(['X', 'Y', 'Z'], sep=' in '))
# 0 Alice in X
# 1 Bob in Y
# 2 Charlie in Z
# Name: name, dtype: object
也可以通过指定一个元素为pandas.Series的列表或一个列表作为第一个参数来连接多个字符串。
print(df['name'].str.cat([df['state'], ['X', 'Y', 'Z']], sep='-'))
# 0 Alice-NY-X
# 1 Bob-CA-Y
# 2 Charlie-CA-Z
# Name: name, dtype: object
可以将第一个参数指定为pandas.Series或它们的一个或多个列表,仅指定字符串是错误的。
# print(df['name'].str.cat('X', sep='-'))
# ValueError: Did you mean to supply a `sep` keyword?
+运算符
您可以简单地使用+运算符。这可能更直观。
print(df['name'] + df['state'])
# 0 AliceNY
# 1 BobCA
# 2 CharlieCA
# dtype: object
可以将相同的字符串连接到所有元素。
print(df['name'] + ' in ' + df['state'])
# 0 Alice in NY
# 1 Bob in CA
# 2 Charlie in CA
# dtype: object
具有相同数量的元素和列表串联的NumPy数组ndarray也是可。
print(df['name'] + ' in ' + df['state'] + ' - ' + ['X', 'Y', 'Z'])
# 0 Alice in NY - X
# 1 Bob in CA - Y
# 2 Charlie in CA - Z
# dtype: object
NaN缺失值的处理
如果包含缺失值NaN。
df['col_NaN'] = ['X', pd.np.nan, 'Z']
print(df)
# name age state point col_NaN
# 0 Alice 24 NY 64 X
# 1 Bob 42 CA 92 NaN
# 2 Charlie 18 CA 70 Z
在str.cat()中,包含缺失值NaN的元素默认情况下变为缺失值NaN。
print(df['name'].str.cat(df['col_NaN'], sep='-'))
# 0 Alice-X
# 1 NaN
# 2 Charlie-Z
# Name: name, dtype: object
可以替换为参数na_rep指定的字符串。
print(df['name'].str.cat(df['col_NaN'], sep='-', na_rep='No Data'))
# 0 Alice-X
# 1 Bob-No Data
# 2 Charlie-Z
# Name: name, dtype: object
即使使用+运算符,包含缺失值NaN的元素也将变为缺失值NaN。
print(df['name'] + '-' + df['col_NaN'])
# 0 Alice-X
# 1 NaN
# 2 Charlie-Z
# dtype: object
如果要将缺失值NaN替换为任意值,请使用fillna()。
字符串列和数值列的连接
当组合字符串列和数字列时,必须通过astype()方法将数字列转换为字符串类型str。
# print(df['name'].str.cat(df['age'], sep='-'))
# TypeError: sequence item 1: expected str instance, int found
print(df['name'].str.cat(df['age'].astype(str), sep='-'))
# 0 Alice-24
# 1 Bob-42
# 2 Charlie-18
# Name: name, dtype: object
同样适用于+运算符。
# print(df['name'] + '-' + df['age'])
# TypeError: can only concatenate str (not "int") to str
print(df['name'] + '-' + df['age'].astype(str))
# 0 Alice-24
# 1 Bob-42
# 2 Charlie-18
# dtype: object
将串联的列添加到pandas.DataFrame
如果要将字符串连接的字符串作为新列添加到pandas.DataFrame中,请在[列名]中指定一个新列名并替换它。
df['name_state'] = df['name'].str.cat(df['state'], sep=' in ')
print(df)
# name age state point col_NaN name_state
# 0 Alice 24 NY 64 X Alice in NY
# 1 Bob 42 CA 92 NaN Bob in CA
# 2 Charlie 18 CA 70 Z Charlie in CA
可以使用drop()方法删除不再需要的列。
print(df.drop(columns=['name', 'state']))
# age point col_NaN name_state
# 0 24 64 X Alice in NY
# 1 42 92 NaN Bob in CA
# 2 18 70 Z Charlie in CA
还有一种使用assign()的方法。使用assign()时,原始对象不会更改,并且会返回一个新对象。
df = pd.read_csv('./data/11/sample_pandas_normal.csv').head(3)
print(df)
# name age state point
# 0 Alice 24 NY 64
# 1 Bob 42 CA 92
# 2 Charlie 18 CA 70
print(df.assign(name_state=df['name'] + ' in ' + df['state']))
# name age state point name_state
# 0 Alice 24 NY 64 Alice in NY
# 1 Bob 42 CA 92 Bob in CA
# 2 Charlie 18 CA 70 Charlie in CA
print(df.assign(name_state=df['name'] + ' in ' + df['state']).drop(columns=['name', 'state']))
# age point name_state
# 0 24 64 Alice in NY
# 1 42 92 Bob in CA
# 2 18 70 Charlie in CA