【问题标题】:Split pandas column into new columns in presence of NaN在存在 NaN 的情况下将 pandas 列拆分为新列
【发布时间】:2015-04-07 03:20:11
【问题描述】:

我有一个 Pandas DataFrame,其中包含一个字符串列,需要拆分为两个单独的列。我在this 问题上找到的使用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。我还考虑过以某种方式在创建中间 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?

【问题讨论】:

    标签: python pandas dataframe nan


    【解决方案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')
    

    【讨论】:

    • 优秀。我只是在 str 方法上加快速度,但是这个看起来对于解析我将来看到的一些更复杂的文件非常有用(当你无法控制文件时很方便格式...)
    【解决方案2】:

    如果您在拆分后再次使用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,而不是引发错误。

    【讨论】:

    • 完美!我没有意识到您可以像这样使用str - 这两个答案都非常好,因为它们不需要tolist() 有趣的业务。
    • 这大约是我建议的 str.extract 方法的两倍(尤其是在应用于更大的 DataFrame 时)。
    猜你喜欢
    • 2019-06-25
    • 1970-01-01
    • 2019-03-01
    • 2016-05-08
    • 2021-01-24
    • 1970-01-01
    • 2019-01-09
    • 2019-04-25
    • 2018-05-28
    相关资源
    最近更新 更多