python-3.x - 来自不同格式数据帧的新数据帧
问题描述
如果可以用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 等的信息,但不确定如何使用此代码使其中一些选项起作用。谢谢!
解决方案
从逻辑上讲,您混合了作为行的一部分和列的一部分的键。构造一个 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
……
推荐阅读
- python - Python日志记录 - 每次循环迭代的新日志文件
- c# - WebApi 请求中的取消
- python - 当 N 大于组数时 nlargest(N) 的行为?
- reactjs - React:读取在 history.push 中作为参数传递的数据
- python - 是否有与 SqlAlchemy 数据库无关的 FROM_UNIXTIME() 函数?
- mysql - 比较两个表并删除与两列比较的公共行
- javascript - 角度 ui-calendar calendar.fullCalendar 不是函数
- python - 为不同时间值设置 x 轴值的范围 - Plotly Python
- android - 后按时从活动中管理片段代码
- jquery - 从模态对话框中卸载 js 文件引用