使用pandas分割DataFrame行

3

我目前正在寻求一种有效的方法将单个pandas DataFrame行拆分为多个略有不同的行。 想象这样的结构:

    A  C1  C2  C3  C4
1   a   b   c   a
2   b   a   e   b   a
3   g   c
4   d   e

我希望你最终能够得到这样的结构:

    A   C
1   a   b
2   a   c
3   a   a
4   b   a
5   b   e
6   b   b
7   b   a
8   g   c
9   d   e
10  d   e

到目前为止,我一直在使用for循环来创建数据字典(df是我的数据框):

rows = []
for i, r in df.iterrows():
  tmp = r[1:].dropna()
  for c in tmp.values:
    dict = {'A': r[0], 'C': c}
    rows.append(dict)

很不幸,这种方法非常缓慢。到目前为止,在使用 pandas 时只使用它可以显著提高执行时间,但我没有足够的经验来找出如何使此案例更快。

有人能给些建议吗?可以采取什么措施加速?

1个回答

3

试试这个:

In [10]: pd.melt(df, id_vars='A', value_vars=['C1','C2','C3','C4'])
Out[10]:
    A variable value
0   a       C1     b
1   b       C1     a
2   g       C1     c
3   d       C1     e
4   a       C2     c
5   b       C2     e
6   g       C2   NaN
7   d       C2   NaN
8   a       C3     a
9   b       C3     b
10  g       C3   NaN
11  d       C3   NaN
12  a       C4   NaN
13  b       C4     a
14  g       C4   NaN
15  d       C4   NaN

如果你想消除NaN:

In [15]: pd.melt(df, id_vars='A', value_vars=['C1','C2','C3','C4'], value_name='C')[['A','C']].dropna()
Out[15]:
    A  C
0   a  b
1   b  a
2   g  c
3   d  e
4   a  c
5   b  e
8   a  a
9   b  b
13  b  a

相同的操作,但动态地选择 C* 列:
In [21]: (pd.melt(df, id_vars='A',
   ....:          value_vars=df.filter(like='C').columns.tolist(),
   ....:          value_name='C')[['A','C']]
   ....:    .dropna()
   ....: )
Out[21]:
    A  C
0   a  b
1   b  a
2   g  c
3   d  e
4   a  c
5   b  e
8   a  a
9   b  b
13  b  a

非常感谢您的出色答案。我已经为选择所有 C* 列创建了另一种方法:pd.melt(df, id_vars='A', value_vars=list(df.columns[1:]), value_name='C')[['A','C']].dropna()。我猜这是一种更通用的方法。 - sebap123
@sebap123,看起来更好了,但它不适用于这组列:['C1','A','C2','C3',...] - MaxU - stand with Ukraine
我完全同意。但在这种情况下,我可能会执行 list(df.columns[0]) + list(df.columns[2:]) - sebap123
@sebap123,如果你有44列,并且其中6个C*列随机分布在它们之间呢? ;) - MaxU - stand with Ukraine
那么我可能需要想出其他的方法。我的想法更加通用,换句话说 - 如果我除了“C *”列还有“F *”,“G *” ... 我也想在这里合并。 在我的示例情况下,您的方法很好。 - sebap123
@sebap123,我同意你的观点!我只是想说filter()函数非常灵活,可能非常有用 :) - MaxU - stand with Ukraine

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接