pandas 将两列合并为空值
pandas combine two columns with null values
我有一个包含两列的 df,我想合并两列而忽略 NaN 值。问题是有时两列都有 NaN 值,在这种情况下我希望新列也有 NaN。这是示例:
df = pd.DataFrame({'foodstuff':['apple-martini', 'apple-pie', None, None, None], 'type':[None, None, 'strawberry-tart', 'dessert', None]})
df
Out[10]:
foodstuff type
0 apple-martini None
1 apple-pie None
2 None strawberry-tart
3 None dessert
4 None None
我尝试使用 fillna
并解决了这个问题:
df['foodstuff'].fillna('') + df['type'].fillna('')
我得到了:
0 apple-martini
1 apple-pie
2 strawberry-tart
3 dessert
4
dtype: object
第4行变成了空白值。在这种情况下我想要的是一个 NaN 值,因为两个组合列都是 NaN。
0 apple-martini
1 apple-pie
2 strawberry-tart
3 dessert
4 None
dtype: object
您始终可以用 None
填充新列中的空字符串
import numpy as np
df['new_col'].replace(r'^\s*$', np.nan, regex=True, inplace=True)
完整代码:
import pandas as pd
import numpy as np
df = pd.DataFrame({'foodstuff':['apple-martini', 'apple-pie', None, None, None], 'type':[None, None, 'strawberry-tart', 'dessert', None]})
df['new_col'] = df['foodstuff'].fillna('') + df['type'].fillna('')
df['new_col'].replace(r'^\s*$', np.nan, regex=True, inplace=True)
df
输出:
foodstuff type new_col
0 apple-martini None apple-martini
1 apple-pie None apple-pie
2 None strawberry-tart strawberry-tart
3 None dessert dessert
4 None None NaN
在一列上使用 fillna
,填充值为另一列:
df['foodstuff'].fillna(df['type'])
结果输出:
0 apple-martini
1 apple-pie
2 strawberry-tart
3 dessert
4 None
fillna
两列一起
sum(1)
添加他们
replace('', np.nan)
df.fillna('').sum(1).replace('', np.nan)
0 apple-martini
1 apple-pie
2 strawberry-tart
3 dessert
4 NaN
dtype: object
您可以使用 combine
方法和 lambda
:
df['foodstuff'].combine(df['type'], lambda a, b: ((a or "") + (b or "")) or None, None)
(a or "")
returns ""
如果 a 是 None
那么相同的逻辑将应用于连接(如果 a 是 None
连接是一个空字符串)。
您可以用列名替换非零值,例如
df1= df.replace(1, pd.Series(df.columns, df.columns))
将 0 替换为空字符串,然后合并如下列
f = f.replace(0, '')
f['new'] = f.First+f.Second+f.Three+f.Four
参考下面的完整代码。
import pandas as pd
df = pd.DataFrame({'Second':[0,1,0,0],'First':[1,0,0,0],'Three':[0,0,1,0],'Four':[0,0,0,1], 'cl': ['3D', 'Wireless','Accounting','cisco']})
df2=pd.DataFrame({'pi':['Accounting','cisco','3D','Wireless']})
df1= df.replace(1, pd.Series(df.columns, df.columns))
f = pd.merge(df1,df2,how='right',left_on=['cl'],right_on=['pi'])
f = f.replace(0, '')
f['new'] = f.First+f.Second+f.Three+f.Four
df1:
In [3]: df1
Out[3]:
Second First Three Four cl
0 0 First 0 0 3D
1 Second 0 0 0 Wireless
2 0 0 Three 0 Accounting
3 0 0 0 Four cisco
df2:
In [4]: df2
Out[4]:
pi
0 Accounting
1 cisco
2 3D
3 Wireless
最终 df 将是:
In [2]: f
Out[2]:
Second First Three Four cl pi new
0 First 3D 3D First
1 Second Wireless Wireless Second
2 Three Accounting Accounting Three
3 Four cisco cisco Four
我们可以使这个问题更加完善,并为此类问题提供通用的解决方案。
其中的关键是我们希望将一组列连接在一起但忽略 NaN
s。
这是我的回答:
df = pd.DataFrame({'foodstuff':['apple-martini', 'apple-pie', None, None, None],
'type':[None, None, 'strawberry-tart', 'dessert', None],
'type1':[98324, None, None, 'banan', None],
'type2':[3, None, 'strawberry-tart', np.nan, None]})
df=df.fillna("NAN")
df=df.astype('str')
df["output"] = df[['foodstuff', 'type', 'type1', 'type2']].agg(', '.join, axis=1)
df['output'] = df['output'].str.replace('NAN, ', '')
df['output'] = df['output'].str.replace(', NAN', '')
如果您处理的列包含其他列不包含的内容,反之亦然,一个行之有效的方法是
>>> df.rename(columns={'type': 'foodstuff'}).stack().unstack()
foodstuff
0 apple-martini
1 apple-pie
2 strawberry-tart
3 dessert
...如果您有多个要“复杂”的列,只要您可以定义 ~.rename
映射,哪种解决方案也能很好地概括。这种重命名背后的目的是创建副本,然后 ~.stack().unstack()
将为您处理。
如前所述,此解决方案仅适用于具有正交列的配置,即永远不会同时赋值的列。
我有一个包含两列的 df,我想合并两列而忽略 NaN 值。问题是有时两列都有 NaN 值,在这种情况下我希望新列也有 NaN。这是示例:
df = pd.DataFrame({'foodstuff':['apple-martini', 'apple-pie', None, None, None], 'type':[None, None, 'strawberry-tart', 'dessert', None]})
df
Out[10]:
foodstuff type
0 apple-martini None
1 apple-pie None
2 None strawberry-tart
3 None dessert
4 None None
我尝试使用 fillna
并解决了这个问题:
df['foodstuff'].fillna('') + df['type'].fillna('')
我得到了:
0 apple-martini
1 apple-pie
2 strawberry-tart
3 dessert
4
dtype: object
第4行变成了空白值。在这种情况下我想要的是一个 NaN 值,因为两个组合列都是 NaN。
0 apple-martini
1 apple-pie
2 strawberry-tart
3 dessert
4 None
dtype: object
您始终可以用 None
填充新列中的空字符串import numpy as np
df['new_col'].replace(r'^\s*$', np.nan, regex=True, inplace=True)
完整代码:
import pandas as pd
import numpy as np
df = pd.DataFrame({'foodstuff':['apple-martini', 'apple-pie', None, None, None], 'type':[None, None, 'strawberry-tart', 'dessert', None]})
df['new_col'] = df['foodstuff'].fillna('') + df['type'].fillna('')
df['new_col'].replace(r'^\s*$', np.nan, regex=True, inplace=True)
df
输出:
foodstuff type new_col
0 apple-martini None apple-martini
1 apple-pie None apple-pie
2 None strawberry-tart strawberry-tart
3 None dessert dessert
4 None None NaN
在一列上使用 fillna
,填充值为另一列:
df['foodstuff'].fillna(df['type'])
结果输出:
0 apple-martini
1 apple-pie
2 strawberry-tart
3 dessert
4 None
fillna
两列一起sum(1)
添加他们replace('', np.nan)
df.fillna('').sum(1).replace('', np.nan)
0 apple-martini
1 apple-pie
2 strawberry-tart
3 dessert
4 NaN
dtype: object
您可以使用 combine
方法和 lambda
:
df['foodstuff'].combine(df['type'], lambda a, b: ((a or "") + (b or "")) or None, None)
(a or "")
returns ""
如果 a 是 None
那么相同的逻辑将应用于连接(如果 a 是 None
连接是一个空字符串)。
您可以用列名替换非零值,例如
df1= df.replace(1, pd.Series(df.columns, df.columns))
将 0 替换为空字符串,然后合并如下列
f = f.replace(0, '') f['new'] = f.First+f.Second+f.Three+f.Four
参考下面的完整代码。
import pandas as pd
df = pd.DataFrame({'Second':[0,1,0,0],'First':[1,0,0,0],'Three':[0,0,1,0],'Four':[0,0,0,1], 'cl': ['3D', 'Wireless','Accounting','cisco']})
df2=pd.DataFrame({'pi':['Accounting','cisco','3D','Wireless']})
df1= df.replace(1, pd.Series(df.columns, df.columns))
f = pd.merge(df1,df2,how='right',left_on=['cl'],right_on=['pi'])
f = f.replace(0, '')
f['new'] = f.First+f.Second+f.Three+f.Four
df1:
In [3]: df1
Out[3]:
Second First Three Four cl
0 0 First 0 0 3D
1 Second 0 0 0 Wireless
2 0 0 Three 0 Accounting
3 0 0 0 Four cisco
df2:
In [4]: df2
Out[4]:
pi
0 Accounting
1 cisco
2 3D
3 Wireless
最终 df 将是:
In [2]: f
Out[2]:
Second First Three Four cl pi new
0 First 3D 3D First
1 Second Wireless Wireless Second
2 Three Accounting Accounting Three
3 Four cisco cisco Four
我们可以使这个问题更加完善,并为此类问题提供通用的解决方案。
其中的关键是我们希望将一组列连接在一起但忽略 NaN
s。
这是我的回答:
df = pd.DataFrame({'foodstuff':['apple-martini', 'apple-pie', None, None, None],
'type':[None, None, 'strawberry-tart', 'dessert', None],
'type1':[98324, None, None, 'banan', None],
'type2':[3, None, 'strawberry-tart', np.nan, None]})
df=df.fillna("NAN")
df=df.astype('str')
df["output"] = df[['foodstuff', 'type', 'type1', 'type2']].agg(', '.join, axis=1)
df['output'] = df['output'].str.replace('NAN, ', '')
df['output'] = df['output'].str.replace(', NAN', '')
如果您处理的列包含其他列不包含的内容,反之亦然,一个行之有效的方法是
>>> df.rename(columns={'type': 'foodstuff'}).stack().unstack()
foodstuff
0 apple-martini
1 apple-pie
2 strawberry-tart
3 dessert
...如果您有多个要“复杂”的列,只要您可以定义 ~.rename
映射,哪种解决方案也能很好地概括。这种重命名背后的目的是创建副本,然后 ~.stack().unstack()
将为您处理。
如前所述,此解决方案仅适用于具有正交列的配置,即永远不会同时赋值的列。