【问题标题】:Split multiple columns with multiple delimiters; Newly-formed columns should have count of original values使用多个分隔符拆分多个列;新形成的列应该有原始值的计数
【发布时间】:2021-04-01 03:24:48
【问题描述】:

我是 python 编程的新手。我处理的数据是在单个超集(即列/属性)中获得某些属性的子集(使用非字母数字分隔符)。

代表性数据:

col1 col2 col3
1 x/x/z/z/z i\i\i\j
2 y/y/z/w/w/w k\k\i

首选输出:

col1 w_col2 x_col2 y_col2 z_col2 i_col3 j_col3 k_col3
1 0 2 0 3 3 1 0
2 3 0 2 1 1 0 2

我通常做什么:

  1. 为此类列查找唯一条目
  2. 单独拆分所有此类列;应用列前缀(可选);存储为新数据框
  3. 在轴 1 上应用 value_counts()
  4. 与原始数据框连接

幸运的是,数据集很小,可以处理已知的列。但是,我想知道是否有更好(紧凑)的方法来解决这个问题。


编辑:

  • 添加了新列,其中值将被视为(转换)为数字(因为它们是计数)
col1 col2 col3 col4 col5
1 x/x/z/z/z i\i\i\j 0-2-4-2 1_2_5_3
2 y/y/z/w/w/w k\k\i 1-3-2-2 4_1_3_4

新的首选输出:

col1 w_col2 x_col2 y_col2 z_col2 i_col3 j_col3 k_col3 0_col4 1_col4 2_col4 3_col4 0_col5 1_col5 2_col5 3_col5
1 0 2 0 3 3 1 0 0 2 4 2 1 2 5 3
2 3 0 2 1 1 0 2 1 3 2 2 4 1 3 4

【问题讨论】:

    标签: python pandas split count


    【解决方案1】:

    这是一个使用 df.stack 的提案,然后是 series.split,然后是 series.explodepd.crosstab

    u = df[['col2','col3']].stack().str.split(r"\\|/").explode()
    v = u.add("_"+ u.index.get_level_values(1))
    
    out = pd.crosstab(v,v.index.get_level_values(0)).T.rename_axis(index=None,columns=None)
    

    print(out)
    
       i_col3  j_col3  k_col3  w_col2  x_col2  y_col2  z_col2
    0       3       1       0       0       2       0       3
    1       1       0       2       3       0       2       1
    

    编辑:

    根据已编辑的问题,您可以对 col4 和 col5 执行类似的步骤,然后 concat:

    u = df[['col2','col3']].stack().str.split(r"\\|/").explode()
    v = u.add("_"+ u.index.get_level_values(1))
    
    a = df[['col4','col5']].stack().str.split("-|_",expand=True).unstack()
    a.columns = a.columns.map("{0[0]}_{0[1]}".format)
    
    out = (pd.concat((df[['col1']],
                      pd.crosstab(v,v.index.get_level_values(0))
                         .T.rename_axis(index=None,columns=None),
                      a),axis=1))
    print(out)
    

       col1  i_col3  j_col3  k_col3  w_col2  x_col2  y_col2  z_col2 0_col4 0_col5  \
    0     1       3       1       0       0       2       0       3      0      1   
    1     2       1       0       2       3       0       2       1      1      4   
    
      1_col4 1_col5 2_col4 2_col5 3_col4 3_col5  
    0      2      2      4      5      2      3  
    1      3      1      2      3      2      4 
    

    【讨论】:

    • 注意:您可以使用df[['col1']].join(out)col1 包含在最终输出中。
    • @nyasa,你想如何将它加入到输出中。我目前不在我的电脑上,所以无法测试,但如果你这样做 pd.DataFrame(df['col4'].str.split(r'//').tolist()) 然后将其加入输出。那是你要的吗?如果不能编辑问题或发布您认为最好的新问题:)
    • @nyasa try df['col4'].str.split(r'//',expand=True) 可能是:-) 这应该为您提供一个数据框,其中包含拆分为单独列的值。然后你就可以加入dfs了。很抱歉给您带来不便,我出去工作了,暂时不在电脑前
    • @nyasa 编辑了更新问题的完整代码。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-06-07
    • 2019-05-11
    • 1970-01-01
    • 2022-11-25
    • 2022-01-18
    • 1970-01-01
    相关资源
    最近更新 更多