【问题标题】:Split each row into multiple rows merging columns将每一行拆分为多行合并列
【发布时间】:2017-08-24 17:19:56
【问题描述】:

更新我的问题以使其更清楚。 我有一个包含多个列/行的 CSV 文件。 我是这样读的

in_csv = pd.read_csv(inputFileName.csv)

一般来说,列是这种格式

Col1,Col2,Col3,JK,KK,...,Def1, Def_1x,Def_1y,Def2,Def_2x,Def_2y

某些行的值位于Def1Def_1xDef_1yDef2Def_2xDef_2y。其他行仅在 Def1Def_1xDef_1y 中具有值。 我想在另一个 csv 中输出如下:

  1. 新行有列Col1,Col2,Col3,JK,KK,...,Def1,Def_1x,Def_1y(没有Def2Def_2xDef_2y
  2. 如果输入 csv 中的 row_iDef_2xDef_2y 中没有值,则在输出 csv 中复制同一行(没有最后三个列)
  3. 如果输入 csv 中的 row_jDef_2xDef_2y 中有值,则在输出 csv 中将其拆分为两行。第一行包含Def1Def_1xDef_1y,第二行包含Def2Def_2xDef_2y 中的值复制到输出csv 的Def1Def_1xDef_1y 李>
  4. 将一行拆分为两行后,保持相同的行顺序
  5. 最后 6 列全部为空的行,保持原样

示例输入:

Col1,Col2,Col3,JK,KK,...,Def1, Def_1x,Def_1y,Def2,Def_2x,Def_2y
A1,B1,C1,....,a,0.2,0.3,,,
A2,B2,C2,.....,b,0.4,0.5,b,0.6,0.7
A3,B3,C3,.....,b,0.8,0.9,,,
A4,B4,C4,.....,,,,,,

预期输出:

Col1,Col2,Col3,JK,KK,...,Def1, Def_1x,Def_1y
A1,B1,C1,....,a,0.2,0.3
A2,B2,C2,.....,b,0.4,0.5
A2,B2,C2,.....,b,0.6,0.7
A3,B3,C3,.....,b,0.8,0.9
A4,B4,C4,.....,,,

行的顺序相同A1A2A2A3A4。拆分一行后,副本将出现在正下方,而不是 csv 的底部。

如果我可以像下面这样添加另一列 (RANK),我将非常感激。对于未拆分的行,它基本上始终为 1。和 1:2 用于分成两行的行。

Col1,Col2,Col3,JK,KK,...,RANK,Def1, Def_1x,Def_1y
A1,B1,C1,....,1,a,0.2,0.3
A2,B2,C2,.....,1,b,0.4,0.5
A2,B2,C2,.....,2,b,0.6,0.7
A3,B3,C3,.....,1,b,0.8,0.9
A4,B4,C4,.....,,,,

非常感谢。

【问题讨论】:

  • 你能贴出你试过的代码吗?
  • 如上所述,我是 python 新手,我所做的只是使用 pd.read_csv 读取输入 csv

标签: python pandas csv dataframe


【解决方案1】:

使用concat() 堆叠XY 条目。

df 作为 Pandas 数据框:

  Col1 Col2   X1   X2   Y1   Y2
0   A1   B1  0.2  0.3  NaN  NaN
1   A2   B2  0.4  0.5  0.6  0.7

XY 条目分开,然后concat()

y_cols = ['Y1','Y2']
x_cols = ['X1','X2']
non_y_cols = df.columns[~df.columns.isin(y_cols)]
non_x_cols = df.columns[~df.columns.isin(x_cols)]
pd.concat([df[non_y_cols], 
           df[non_x_cols].dropna().rename(columns={'Y1':'X1','Y2':'X2'})])

  Col1 Col2   X1   X2
0   A1   B1  0.2  0.3
1   A2   B2  0.4  0.5
1   A2   B2  0.6  0.7

【讨论】:

  • 您的代码错误的第三列显示“IndexError:数组索引过多”。我的 csv 实际上有 22 列和 155 行。在我用 pd.read_csv 读取 csv 文件返回的变量替换 df 后,我正在使用你的脚本。有什么想法吗?
  • 你的意思是我的代码的第三行吗? non_y_cols 分配?您能否确认该代码适用于您最初提供的示例数据?我刚刚在您的示例数据中添加了一些额外的列和行,我没有收到错误。
  • 是的,我的意思是第三排。对不起!这是我的代码: in_csv_dt = pd.read_csv(csvFileName) 然后您的代码使用 in_csv_dt 而不是 df,例如: non_x_cols=in_csv_dt.columns[~in_csv_dt.columns.isin(x_cols)] 等。我可以检查代码上面的示例在蜘蛛编辑器上查看。
  • 听起来您的实际数据中可能存在边缘情况,而您提供的示例数据中没有考虑到这种情况。提供MCVE 确实很有价值——有时只是这样做可以帮助我解决问题并识别边缘情况。如果这些解决方案不适用于您的实际数据,请考虑使用具有代表性的 MCVE 更新您的原始帖子。 (John Galt 的解决方案有效吗?)
  • 我尝试了上面相同的数据,它显示了同样的问题。实际上我认为这是因为 ~in_dcv_dt.isin(y_cols) 没有返回预期的结果。这是它的输出(全部为真) Col1 Col2 X1 X2 Y1 Y2 0 True True True True True True 1 True True True True True True
【解决方案2】:

这是一种方法

In [1580]: pd.concat(
             [df.loc[:,cols.str.contains(p)]
                .rename(columns={'Y1':'X1','Y2':'X2'})
                .dropna() for p in ['Col|X', 'Col|Y']],
             ignore_index=True)
Out[1580]:
  Col1 Col2   X1   X2
0   A1   B1  0.2  0.3
1   A2   B2  0.4  0.5
2   A2   B2  0.6  0.7

【讨论】:

  • 谢谢高尔特。如果我在第一列和 X/Y 之间有多个其他列,我该如何概括这一点。我试图让上面的例子变得简单,对此感到抱歉。 Col1, Col2, AB, XX, YY, JK, X1,X2,X3,Y1,Y2,Y3 A1,B1,......,0.2,0.3,a,,, A2,B2,......, 0.4,0.5,b,0.6,0.7,b 输出与最初预期的一样,保留从 Col1 ...到 JK 的所有列。然后 [Y1,Y2,Y3] -> [X1,X3,X3] 所以基本上如何概括这个: p in ['Col|X', 'Col|Y']
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-02-22
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多