Python 在NaN在场的情况下将pandas列拆分为新列

Python 在NaN在场的情况下将pandas列拆分为新列,python,pandas,dataframe,nan,Python,Pandas,Dataframe,Nan,我有一个包含字符串列的数据框,它需要拆分为两个单独的列。我在SO from问题上找到的使用tolist的答案很有魅力,除非我的专栏包含NaN。下面的摘录描述了困难: import pandas as pd import numpy as np # Example DataFrame df = pd.DataFrame([[25.0, '34.2/ 18.1', 'one'], [32.6, '28.6/ 17.9', 'two'],

我有一个包含字符串列的数据框,它需要拆分为两个单独的列。我在SO from问题上找到的使用
tolist
的答案很有魅力,除非我的专栏包含NaN。下面的摘录描述了困难:

import pandas as pd
import numpy as np

# Example DataFrame
df = pd.DataFrame([[25.0, '34.2/ 18.1', 'one'],
                   [32.6, '28.6/ 17.9', 'two'],
                   [12.5, '30.1/ 17.6', 'three']], columns=['A', 'B', 'C'])
df2 = df.copy()

# This method works when all data are present
df['D'] = pd.DataFrame(df['B'].str.split('/').tolist())[1]

# However, when there are NaNs:
df2['B'][0] = np.nan

# This line fails
df2['D'] = pd.DataFrame(df2['B'].str.split('/').tolist())[1]
它给了我一个
KeyError
,因为中间数据帧只有一列,这表明返回列表的麻烦不再起作用:

               0
0            NaN
1  [28.6,  17.9]
2  [30.1,  17.6]
我尝试先通过
pd.DataFrame(df2['B'].str.split('/').dropna().tolist())
删除NaN,但随后我丢失了索引。。。我需要将NaN保持在索引0。我还想过在创建中间数据帧时以某种方式复制NaN以强制两列,但我没有运气

这就是我需要的df2数据的外观:

      A           B      C     D
0  25.0         NaN    one   NaN
1  32.6  28.6/ 17.9    two  17.9
2  12.5  30.1/ 17.6  three  17.6
有没有一种不用列表作为中介的方法?或者以某种方式处理NaN?

允许您提供正则表达式模式。模式中的每个组作为单独的列返回<代码>NaN在未找到匹配项时使用:

df2['D'] = df2['B'].str.extract(r'/(.*)')
print(df2)
屈服

      A           B      C      D
0  25.0         NaN    one    NaN
1  32.6  28.6/ 17.9    two   17.9
2  12.5  30.1/ 17.6  three   17.6
请注意,如果希望将
D
列视为浮点数,则还需要调用
astype

df2['D'] = df2['D'].astype('float')

如果在拆分后再次使用
str
访问器(而不是使用
tolist()
并生成另一个数据帧),则可以继续使用您的方法:


如果索引不存在,则返回
NaN
,而不是引发错误。

完美!我没有意识到你可以像那样使用
str
——这两个答案都是双倍的好,因为它们不需要
tolist()
有趣的业务。这大约是我建议的
str.extract
方法的两倍(特别是当应用于更大的数据帧时)。非常好。我刚刚开始学习
str
方法,但是这一个对于解析我将来看到的一些更复杂的文件非常有用(在无法控制文件格式时非常方便…)
>>> df2['D'] = df2['B'].str.split('/').str[-1]
>>> df2
      A           B      C      D
0  25.0         NaN    one    NaN
1  32.6  28.6/ 17.9    two   17.9
2  12.5  30.1/ 17.6  three   17.6