根据两列中的文本拆分行(Python,Pandas)

Posted

技术标签:

【中文标题】根据两列中的文本拆分行(Python,Pandas)【英文标题】:Split rows according to text in two columns (Python, Pandas) 【发布时间】:2016-11-19 01:33:48 【问题描述】:

这是我的数据框(有更多的字母,长度约为 35.5k)以及 - 是其他相关字符串的东西)。所有变量都是字符串,['C1','C2'] 是 MultiIndex。

tmp

C1    C2     C3    C4    C5    Start    End     C8
A     1      -      -     -    12       14      -
A     2      -      -     -    1,4,7    3,6,10  -
A     3      -      -     -    16,19    17,21   -
A     4      -      -     -    22       24      -

我需要它变成这样(拆分包含逗号的每一行来维护其他所有内容):

C1    C2     C3    C4    C5    Start  End   C8   Appearance
A     1      -      -     -    12     14    -    1
A     2      -      -     -    1      3     -    1
A     2      -      -     -    4      6     -    2
A     2      -      -     -    7      10    -    3
A     3      -      -     -    16     17    -    1
A     3      -      -     -    19     21    -    2
A     4      -      -     -    22     24    -    1

我试过这个脚本 pandas: How do I split text in a column into multiple rows?

作为

s = tmp['Start'].str.split(',').apply(Series, 1).stack()
s.index = s.index.droplevel(-1)
s.name = 'Start
del tmp['Start']
final = tmp.join(s)

但是结果比它应该的要大得多!我得到了数千次重复,这只是试图拆分“开始”。我什至无法想象对 Start 和 End 都这样做(“Start”中的每个逗号都意味着“End”中的逗号。

Lengths:
tmp   = 35568
s     = 35676
final = 293408

【问题讨论】:

这不是预期的吗?如果您连续有 [1, 4, 7],则结果中将有另外两行。 【参考方案1】:

您可以从s1s2 然后join 创建新的df。更好的是在str.split 中使用参数expand=True 并通过drop 删除多个列:

要创建列Appearance,请使用groupby by indexcumcount

s1 = tmp['Start'].str.split(',', expand=True).stack()
s1.index = s1.index.droplevel(-1)
s1.name = 'Start'

s2 = tmp['End'].str.split(',', expand=True).stack()
s2.index = s2.index.droplevel(-1)
s2.name = 'End'
tmp.drop(['Start', 'End'], inplace=True, axis=1)

df = pd.DataFrame('s1':s1, 's2':s2, index=s1.index)
final = tmp.join(df)

final['Appearance'] = final.groupby(final.index).cumcount() + 1
print (final)
  C1  C2 C3 C4 C5 C8  s1  s2  Appearance
0  A   1  -  -  -  -  12  14           1
1  A   2  -  -  -  -   1   3           1
1  A   2  -  -  -  -   4   6           2
1  A   2  -  -  -  -   7  10           3
2  A   3  -  -  -  -  16  17           1
2  A   3  -  -  -  -  19  21           2
3  A   4  -  -  -  -  22  24           1

通过评论编辑:

你可以先试试reset_index

print (tmp)
      C3 C4 C5  Start     End C8
C1 C2                           
A  1   -  -  -     12      14  -
   2   -  -  -  1,4,7  3,6,10  -
   3   -  -  -  16,19   17,21  -
   4   -  -  -     22      24  -

tmp.reset_index(inplace=True)
print (tmp)
  C1  C2 C3 C4 C5  Start     End C8
0  A   1  -  -  -     12      14  -
1  A   2  -  -  -  1,4,7  3,6,10  -
2  A   3  -  -  -  16,19   17,21  -
3  A   4  -  -  -     22      24  -

【讨论】:

"[293408 rows x 7 columns]" 它的行数不应该和s1/s2一样吗? (~35k) 长度s1s2 一样吗? s1 的索引是否与s2 的索引相同? 是的! Start 中的每个逗号都意味着 End 中的一个逗号。 索引中可能有重复项-尝试第一次使用-tmp.reset_index(inplace=True) 有效!!!我相信其他答案也有效,但既然你是第一个,我会打勾。感谢双方。你也可以帮我添加“外观”列吗?【参考方案2】:

我连接扩展的 'Start''End' 列以确保它们匹配,即使它们没有相同数量的条目。

s = tmp.Start.str.split(',', expand=True).stack().rename('Start')
e = tmp.End.str.split(',', expand=True).stack().rename('End')
se = pd.concat([s, e], axis=1).reset_index(1, drop=True)

tmp.drop(['Start', 'End'], axis=1).merge(se, left_index=True, right_index=True)

【讨论】:

TypeError: split() got an unexpected keyword argument 'expand' @Nico 放弃这个论点。您使用的是旧版 pandas。 你的回答也很好;) +1 AttributeError: 'Series' object has no attribute 'stack' @Nico 抱歉,除了建议将您的 pandas 升级到 0.18.1 并尝试 jezrael 的解决方案或再次使用我的解决方案之外,我无法为您解决这个问题。

以上是关于根据两列中的文本拆分行(Python,Pandas)的主要内容,如果未能解决你的问题,请参考以下文章

Pandas: 如何将一列中的文本拆分为多行? | Python

如何根据 pandas-python 中带有空格的图像拆分列中的值

如何根据oracle plsql中列中的逗号分隔值拆分选择查询行

如何根据 Python pandas 中的条件拆分列

Pandas Python 中的条件乘法

pandas 将excel中的一列文本数据拆分成多列 如何操作