在存在NaN的情况下将pandas柱拆分成新柱

时间:2015-02-06 21:19:41

标签: python pandas dataframe nan

我有一个包含字符串列的pandas DataFrame,需要拆分成两个单独的列。我在this问题的SO上找到的使用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,因为中间的DataFrame只有一列,表明去往列表然后回来的麻烦不再能够完成任何事情:

               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中间DataFrame强制两列,但没有运气。

这就是我需要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?

2 个答案:

答案 0 :(得分:4)

如果您在拆分后再次使用str访问者(而不是使用tolist()并制作另一个DataFrame),则可以继续使用您的方法:

>>> 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

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

答案 1 :(得分:1)

The str.extract method允许您提供正则表达式模式。模式中的每个组都作为单独的列返回。找不到匹配项时使用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')