【问题标题】:Split strings in tuples into columns, in Pandas在 Pandas 中将元组中的字符串拆分为列
【发布时间】:2015-06-04 21:14:44
【问题描述】:

我有以下DataFrame,其中Track ID 是行索引。如何将stats 列中的字符串拆分为 5 列数字?

Track ID    stats
14.0    (-0.00924175824176, 0.41, -0.742016492568, 0.0036830094242, 0.00251748449963)
28.0    (0.0411538461538, 0.318230769231, 0.758717081514, 0.00264000622468, 0.0106535783677)
42.0    (-0.0144351648352, 0.168438461538, -0.80870348637, 0.000816872566404, 0.00316572586742)
56.0    (0.0343461538462, 0.288730769231, 0.950844962874, 6.1608706775e-07, 0.00337262030771)
70.0    (0.00905164835165, 0.151030769231, 0.670257006716, 0.0121790506745, 0.00302182567957)
84.0    (-0.0047967032967, 0.171615384615, -0.552879463981, 0.0500316517755, 0.00217970256969)

【问题讨论】:

  • 通过发布数据帧的 df.to_dict() 而不是其字符串表示形式,您将让其他人的事情变得更容易。
  • stats列,它是包含一个看起来像元组的字符串,还是包含元组?
  • 感谢您的意见 - 我处于陡峭学习曲线的底部。我不知道df.to_dict(),但它告诉我数据中的stats 列确实是元组,而不是字符串。例如,使用 [float(x[0]) for x in df['stats']] 给了我第 0 个元素。

标签: python pandas split


【解决方案1】:

对于另一种情况,假设它是看起来像元组的字符串:

In [74]: df['stats'].str[1:-1].str.split(',', expand=True).astype(float)
Out[74]:
          0         1         2         3         4
0 -0.009242  0.410000 -0.742016  0.003683  0.002517
1  0.041154  0.318231  0.758717  0.002640  0.010654
2 -0.014435  0.168438 -0.808703  0.000817  0.003166
3  0.034346  0.288731  0.950845  0.000001  0.003373
4  0.009052  0.151031  0.670257  0.012179  0.003022
5 -0.004797  0.171615 -0.552879  0.050032  0.002180

(注意:对于旧版本的熊猫(return_type='frame'而不是expand关键字)

顺便说一句,如果是元组而不是字符串,您可以简单地执行以下操作:

pd.DataFrame(df['stats'].tolist(), index=df.index)

【讨论】:

  • 感谢您的意见。总的来说,我对 pandas、python 和脚本不熟悉,所以我仍然对基础知识有所了解。 stats 列中的数据确实是元组。用df2 = df['stats'].apply(pd.Series) 创建一个新的DataFrame 让我向前迈进了一大步。再次感谢。
  • return_type 已弃用,取而代之的是 expand=True
  • 请不要使用apply(pd.Series)(或推​​荐使用)。请参阅When should I ever use pandas apply() in my code? 更好的解决方案是先列出该列。
【解决方案2】:

如果您有一个元组序列而不是字符串,并且您希望它们作为 DataFrame 列,这是最简单的方法:

df = pd.concat([df['Track ID'],pd.DataFrame(df['stats'].values.tolist())], axis=1)

如果真的是字符串,可以先转换成这样的列表,然后应用上面的操作:

dfpart = pd.DataFrame(df['stats'].apply(lambda x: x.strip('()').split(', ')).values.tolist()).astype(float)
df = pd.concat([df['Track ID'], dfpart], axis=1)

【讨论】:

    【解决方案3】:

    假设您有一列包含元组(如您的示例中所示)而不是字符串,这将起作用:

    df = pandas.DataFrame({'Track ID': [14, 28, 42], 'stats': [(1, 2, 3, 4, 5), (1, 2, 3, 4, 5), (1, 2, 3, 4, 5)]}).set_index("Track ID")
    
    from operator import itemgetter
    for i in range(5):
        df["Col {}".format(i)] = df.stats.apply(itemgetter(i))
    

    如果你确实有看起来像元组的字符串,你可以先解析它们,然后应用与上面相同的模式:

    df = df2 = pandas.DataFrame({'Track ID': [14, 28, 42], 'stats': ["(1, 2, 3, 4, 5)", "(1, 2, 3, 4, 5)", "(1, 2, 3, 4, 5)"]}).set_index("Track ID")
    df.stats = df2.stats.str.strip("()").str.split(", ")
    

    【讨论】:

      【解决方案4】:

      由于您的 stats 列包含长度为 5 的元组,因此这项工作相当简洁

      pd.concat([df['Track ID'], pd.DataFrame(df['stats'].tolist(), index = 
      df.index, columns = [f'stats_{i}' for i in range(1, 6)])], axis = 1)
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2021-10-01
        • 1970-01-01
        • 2022-12-29
        • 2020-06-10
        • 1970-01-01
        • 2020-02-12
        • 2013-02-04
        • 1970-01-01
        相关资源
        最近更新 更多