我目前有一个代码可以将其转换为:
A B C D E F G H I J 0 1.1.1 amba 50 1 131 4 40 3 150 5 1 2.2.2 erto 50 7 40 8 150 8 131 2 2 3.3.3 gema 131 2 150 5 40 1 50 3
变成这样:
ID User 40 50 131 150 0 1.1.1 amba 3 1 4 5 1 2.2.2 erto 8 7 2 8 2 3.3.3 gema 1 3 2 5
您可以在这里检查代码:
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 50 1 131 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+") print(df1) 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
如果关键列具有唯一值,则程序可以正常工作,但如果存在重复值,则程序会失败。我遇到的问题是,我的实际数据框中有 30 个列的行,其他有 60 个列,其他有 63 个列,等等。因此程序将空值检测为重复,程序会失败。
请检查这个例子:
A B C D E F G H I J 0 1.1.1 amba 50 1 131 4 NaN NaN NaN NaN 1 2.2.2 erto 50 7 40 8 150.0 8.0 131.0 2.0 2 3.3.3 gema 131 2 150 5 40.0 1.0 50.0 3.0
我希望得到这样的东西:
ID User 40 50 131 150 0 1.1.1 amba 1 4 1 2.2.2 erto 8 7 2 8 2 3.3.3 gema 1 3 2 5
如果我尝试将其拆分,则会收到错误“索引包含重复条目,无法重塑”。我一直在阅读有关此内容的文章,df.drop_duplicates、pivot_tables、tc 可以解决此问题,但我无法使用当前代码解决此问题。有关于如何修复此问题的想法吗?谢谢。
当输入的列中存在 NaN 或重复值时,您当前的代码无法正常运行是因为在调用 unstack 时,索引重复会导致错误。为了处理这些情况,可以在转换数据框之前更有效地处理 NaN 值,并确保数据没有重复的索引。
NaN
unstack
以下是修复代码的步骤和改进后的版本:
melt
key
val
pivot_table
以下是完整代码:
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 50 1 131 4 NaN NaN NaN NaN 2.2.2 erto 50 7 40 8 150.0 8.0 131.0 2.0 3.3.3 gema 131 2 150 5 40.0 1.0 50.0 3.0 """), sep="\s+") # 1. 动态地将数据转为 key-value 格式 melted = pd.melt( df1, id_vars=["A", "B"], value_vars=["C", "E", "G", "I"], # Key columns var_name="key_source", # 原始列名 value_name="key" # key 列 ) melted["val"] = pd.melt( df1, id_vars=["A", "B"], value_vars=["D", "F", "H", "J"], # Value columns var_name="val_source", # 原始列名 value_name="val" # val 列 )["val"] # 2. 丢弃 NaN 值 melted = melted.dropna(subset=["key", "val"]) # 3. Pivot 数据,按 `key` 列展开 pivoted = melted.pivot_table( index=["A", "B"], # 保持 ID 和 User 不变 columns="key", # 将 key 展开为列 values="val", # 使用 val 的值 aggfunc="first" # 如果有重复索引,取第一个值 ).reset_index() # 4. 整理列名 pivoted.columns.name = None pivoted.rename(columns={"A": "ID", "B": "User"}, inplace=True) print(pivoted)
对于提供的示例输入,这段代码的输出是:
ID User 40 50 131 150 0 1.1.1 amba NaN 1.0 4.0 NaN 1 2.2.2 erto 8.0 7.0 2.0 8.0 2 3.3.3 gema 1.0 3.0 2.0 5.0
pd.melt
value_vars
aggfunc="first"
您可以将此代码应用于更大或更复杂的数据框,无需担心列数或重复值问题。