Pandas函数中列值赋值失效问题求助
问题分析与解决方案:冷战支持数据重塑赋值错误
首先,咱们先直接解决你的问题,然后再拆解你函数里的错误点——其实用pandas内置的pivot_table就能完美解决这个长转宽的需求,比自己写函数靠谱多了。
正确实现代码
先看完整的工作代码,完全匹配你的目标格式:
import pandas as pd # 模拟你的原始输入数据 data = [ ["Fake", 1984, "US", 1, 1], ["Fake", 1984, "SU", 0, 1], ["Fake", 1985, "US", 1, 1], ["Fake", 1985, "SU", 1, 1], ["florp", 1984, "SU", 1, 1], ["florp", 1985, "SU", 1, 1] ] df = pd.DataFrame(data, columns=["country", "year", "supporting_nation", "eco_sup", "mil_sup"]) # 步骤1:过滤仅保留美、苏的支持记录 filtered_df = df[df["supporting_nation"].isin(["US", "SU"])].copy() # 步骤2:用pivot_table直接转成宽格式,自动聚合同一国家-年份的记录 wide_df = filtered_df.pivot_table( index=["country", "year"], columns="supporting_nation", values=["eco_sup", "mil_sup"], aggfunc="max", # 取最大值,确保同一国家-年份的同一支持国只保留有效记录 fill_value=0 # 没有记录的填充0 ) # 重命名列,改成你要的"US_eco_sup"这种格式 wide_df.columns = [f"{col[1]}_{col[0]}" for col in wide_df.columns] # 添加US_SUP和SU_SUP列:只要经济或军事支持有一项为1,就标记为1 wide_df["US_SUP"] = wide_df[["US_eco_sup", "US_mil_sup"]].max(axis=1) wide_df["SU_SUP"] = wide_df[["SU_eco_sup", "SU_mil_sup"]].max(axis=1) # 重置索引,把country和year从索引转回普通列,再调整列顺序到目标格式 wide_df = wide_df.reset_index() desired_cols = ["country", "year", "US_SUP", "US_eco_sup", "US_mil_sup", "SU_SUP", "SU_eco_sup", "SU_mil_sup"] wide_df = wide_df[desired_cols] print(wide_df)
运行后就会得到你想要的目标格式,所有列的赋值都是正确的。
你的函数出错的核心原因
咱们来拆解你写的函数里的问题:
没有返回修改后的行,导致所有赋值白做了
在pandas的apply方法中,如果你修改传入的行对象x但不返回它,这些修改只会在临时对象上生效,根本不会保存到原DataFrame里。你的函数最后没有return x,所以x[support_cols] = support_vars这一步的操作完全没有被保留,后续groupby的时候这些列还是初始的0值。逻辑覆盖问题,无法同时处理美、苏的记录
当一个国家在同一年同时获得美、苏支持时(比如Fake 1984),你的函数处理其中一行时,nation变量会被覆盖:比如先处理SU的行,nation设为SU_,但接着处理US的行时,nation会被改成US_,导致其中一方的列永远无法被正确赋值。就算你加了返回,也只能处理其中一个支持国的列。索引匹配的潜在问题
你把support_vars(包含eco_sup和mil_sup的Series)赋值给x[support_cols]时,如果列名顺序不匹配,可能会导致赋值错位,但这不是你现在全为0的主要原因,主要还是前两点。
内容的提问来源于stack exchange,提问作者Jasper
相关产品推荐
相关产品推荐

