我想知道用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