首页 > 解决方案 > 来自不同格式数据帧的新数据帧

问题描述

如果可以用python实现这样的事情,我正在徘徊。

我目前有以下数据框(df1):

  A       B       C      D      E      F   
1.1.1   amba     131     1     50      4      
2.2.2   erto     50      7     131     8
3.3.3   gema     131     2     50      5

我想在一个新的数据框(df2)中得到这个输出:

 ID     User    131      50
1.1.1   amba     1       4
2.2.2   erto     8       7
3.3.3   gema     2       5

请记住,df1 的行数不确定,而 df2 的行数应该与 df1 相同。第一列和第二列保持不变。df1 中的 C 和 E 列存储属性 ID,而 D 和 F 列存储属性值。例如,在 df1 中,第一行中的 131=1 和 50=4。Plus 属性 ID 并不总是在同一列中,属性 ID 可以放在 C 列或 E 列中。

我正在考虑使用循环创建 df2 并使用 lambda 分析行,但我目前遇到的问题是暂时无法工作。任何的想法?


我已经理解了代码的每一部分,现在我正在添加列,但我想知道这是否可以通过循环或类似的东西来完成。这是添加 4 个额外列后代码的样子:

import pandas as pd
import io

df1 = pd.read_csv(io.StringIO("""  A       B       C      D      E      F      G      H      I       J     
1.1.1   amba     131     1     50      4      40       3       150       5   
2.2.2   erto     50      7     40      8      150      8       131       2
3.3.3   gema     131     2    150      5      40       1        50       3"""), sep="\s+")



df2 = (pd.concat([df1.drop(columns=["C","D","E","F","G","H"]).rename(columns={"I":"key","J":"val"}),
           df1.drop(columns=["C","D","E","F","I","J"]).rename(columns={"G":"key","H":"val"}),
           df1.drop(columns=["C","D","G","H","I","J"]).rename(columns={"E":"key","F":"val"}),
           df1.drop(columns=["E","F","G","H","I","J"]).rename(columns={"C":"key","D":"val"}),
          ])
 .rename(columns={"A":"ID","B":"User"})
 .set_index(["ID","User","key"])
 .unstack(2)
 .reset_index()
)

# flatten the columns..
df2.columns = [c[1] if c[0]=="val" else c[0] for c in df2.columns.to_flat_index()]
df2


print(df2)

这是输出:

      ID  User  40  50  131  150
0  1.1.1  amba   3   4    1    5
1  2.2.2  erto   8   7    2    8
2  3.3.3  gema   1   3    2    5

所以是的,一切正常,但我想找到一种方法来使用循环而不是有大量的行(我每行大约有 70 列)。非常感谢你的帮助。谢谢。


我只有一个额外的问题,我会让一切正常。在我的实际表中,我有一些行有 60 列,而其他行只有 30 列左右。这意味着我在这些行中有大量的 NaN,列数较少,因此在尝试取消堆叠时出现错误。我已经阅读了有关 pivot_tables、drop_duplicates 等的信息,但不确定如何使用此代码使其中一些选项起作用。谢谢!

标签: python-3.xpandasdataframe

解决方案


从逻辑上讲,您混合了作为行的一部分和列的一部分的键。构造一个 df concat(),将整个键作为行的一部分。那么这是一个简单的使用unstack()来获得你想要的东西

df1 = pd.read_csv(io.StringIO("""  A       B       C      D      E      F   
1.1.1   amba     131     1     50      4      
2.2.2   erto     50      7     131     8
3.3.3   gema     131     2     50      5"""), sep="\s+")


df2 = (pd.concat([df1.drop(columns=["C","D"]).rename(columns={"E":"key","F":"val"}),
           df1.drop(columns=["E","F"]).rename(columns={"C":"key","D":"val"}),
          ])
 .rename(columns={"A":"ID","B":"User"})
 .set_index(["ID","User","key"])
 .unstack(2)
 .reset_index()
)

# flatten the columns..
df2.columns = [c[1] if c[0]=="val" else c[0] for c in df2.columns.to_flat_index()]
df2

输出

    ID  User  50  131
 1.1.1  amba   4    1
 2.2.2  erto   7    8
 3.3.3  gema   5    2

……


推荐阅读