从不同格式的数据帧逐行新建数据帧



我想知道用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等,但不知道如何使用这些代码来实现其中的一些选项。谢谢

从逻辑上讲,键是行和列的一部分。通过concat()构造一个df,该df将整个键作为行的一部分。然后是一个简单的例子,使用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

最新更新