根据文本将行拆分为两列(Python、Pandas)

根据文本将行拆分为两列(Python、Pandas),python,string,pandas,split,multi-index,Python,String,Pandas,Split,Multi Index,这是我的数据帧(包含更多字母,长度约为35.5k)和其他相关字符串。所有变量都是字符串,['C1','C2']是多索引 tmp C1 C2 C3 C4 C5 Start End C8 A 1 - - - 12 14 - A 2 - - - 1,4,7 3,6,10 - A 3 - - - 16,

这是我的数据帧(包含更多字母,长度约为35.5k)和其他相关字符串。所有变量都是字符串,['C1','C2']是多索引

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      -
我需要它变成这样(拆分包含逗号的每一行,以维护所有其他内容):

我试过这个剧本

作为

但是结果比它应该的要大得多!我有数千次重复,这只是试图分割“开始”。我甚至无法想象尝试对开始和结束都这样做(“开始”中的每个逗号都意味着“结束”中的一个逗号)

Lengths:
tmp   = 35568
s     = 35676
final = 293408

您可以从
s1
s2
创建新的
df
,然后。更好的方法是在中使用参数
expand=True
,并通过以下方式删除多列:

要创建列
外观
请使用
groupby
by
index
with

按注释编辑:

您可以先尝试
reset\u 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  -

我对展开的
'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)

“[293408行x 7列]”它的行数不应该与s1/s2的行数相同吗?(~35k)是长度
s1
s2
相同吗?
s1
的索引与
s2
的索引相同吗?是的!开始处的每个逗号都意味着结尾处有一个逗号。可能索引中有重复项-请首先尝试使用-
tmp.reset\u index(inplace=True)
有效!!!我肯定另一个答案也有效,但既然你是第一个,我就给你打勾。多亏了这两个答案。你能帮我添加“外观”列吗?这不是预期的吗?如果一行中有[1,4,7],那么结果中将有两行额外的行。
TypeError:split()得到一个意外的关键字参数“expand”
@Nico请删除该参数。您使用的是较旧的pandas版本。您的答案也很好;)+1
AttributeError:“Series”对象没有属性“stack”
@Nico很抱歉,我无法为您解决此问题,只能建议您将pandas升级到0.18.1,然后再次尝试jezrael或我的解决方案。
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
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  -
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)