【问题标题】:Python - how to split list for creating new column? pandasPython - 如何拆分列表以创建新列?熊猫
【发布时间】:2019-03-27 22:48:46
【问题描述】:

我有一个这样的数据框

    col1    col2 
    [A, B]   1
    [A, C]   2

我想将 col1 分成两列和输出,我想以这种形式输出

col1_A  col1_B  col2
  A       B       1
  A       C       2

我试过这个df['col1'].str.rsplit(',',n=2, expand=True) 但它显示TypeError: list indices must be integers or slices, not str

【问题讨论】:

  • df[['col_A','col_b']]=pd.DataFrame(df['col1'].tolist())

标签: python pandas list split


【解决方案1】:

压缩值和列名并使用插入来获得正确的位置。

for ind,(k,v) in enumerate(zip(zip(*df.pop('col1').tolist()),['col1_A', 'col1_B'])):
    df.insert(ind, v, k)

完整示例

import pandas as pd

df = pd.DataFrame({
    "col1": [['A', 'B'], ['A', 'C']],
    "col2": [1, 2],
})

for ind,(k,v) in enumerate(zip(zip(*df.pop('col1').tolist()),['col1_A', 'col1_B'])):
    df.insert(ind, v, k)

print(df)

返回:

  col1_A col1_B  col2
0      A      B     1
1      A      C     2

【讨论】:

    【解决方案2】:

    你可以这样做:

    >> df_expanded = df['col1'].apply(pd.Series).rename(
         columns = lambda x : 'col1_' + str(x))
    
    >> df_expanded
    
      col1_0 col1_1
    0      A      B
    1      A      C
    

    将这些列添加到原始数据框:

    >> pd.concat([df_expanded, df], axis=1).drop('col1', axis=1)
    
      col1_0 col1_1  col2
    0      A      B     1
    1      A      C     2
    

    如果需要将列命名为行中的第一个元素:

    df_expanded.columns =  ['col1_' + value
                            for value in df_expanded.iloc[0,:].values.tolist()]
    
      col1_A col1_B
    0      A      B
    1      A      C
    

    【讨论】:

    • 数据框类有添加前缀功能。
    • 嗯,重要的是可以将pandas.Series 应用于列
    【解决方案3】:

    join + pop

    df = df.join(pd.DataFrame(df.pop('col1').values.tolist(),
                              columns=['col1_A', 'col1_B']))
    
    print(df)
    
       col2 col1_A col1_B
    0     1      A      B
    1     2      A      C
    

    尝试避免pd.Series.apply 是一种很好的做法,这通常会导致 Python 级别的循环和额外的开销。

    【讨论】:

    • @AntonvBR,我没有查看源代码,但对其进行了测试.. %timeit df['col1'].tolist() vs %timeit df['col1'].values.tolist()。一般来说,(我觉得)Pandas API 似乎给简单的方法增加了非 O(1) 开销:S
    • @AntonvBR,让我担心的是它不是 固定因素 慢。这是 O(n)。确实,Pandas 方法应该能够在适用时直接与 NumPy 方法短路。
    • 也许通过为数据框类设置一些全局设置?或装饰它
    • 好的,我现在正在查看源代码,是的。它是它所做的日期时间控制。区别在于:pd.Series([pd.Timestamp('2018'), pd.Timestamp('2019')]).values.tolist(), pd.Series([pd.Timestamp('2018'), pd.Timestamp('2019')]).tolist()。从我所见,系列值被发送到函数而不是 dtype 控件。处理混合类型?来源:github.com/pandas-dev/pandas/blob/…
    • 很抱歉在这里发布了很多内容.... 好的,所以该函数检查它是否是 datetimelike:所以这个函数github.com/pandas-dev/pandas/blob/… 带有多个或测试......为什么它不能简单地做一个简单的 dtype 检查而不是这个?
    【解决方案4】:

    你可以使用apply:

    import pandas as pd
    df = pd.DataFrame({
        "col1": [['A', 'B'], ['A', 'C']],
        "col2": [1, 2],
    })
    df['col1_A'] = df['col1'].apply(lambda x: x[0])
    df['col1_B'] = df['col1'].apply(lambda x: x[1])
    del df['col1']
    df = df[df.columns[[1,2,0]]]
    print(df)
    
      col1_A col1_B  col2
    0      A      B     1
    1      A      C     2
    

    【讨论】:

    • df['col1'].str[0]
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-08-10
    • 2021-02-28
    • 1970-01-01
    • 2019-11-26
    • 2017-05-29
    • 2023-02-23
    相关资源
    最近更新 更多