使用.loc为DataFrame生成对应列值列表时仅返回单个值的问题
问题
现有如下DataFrame:
| Col1 | Col2 |
|---|---|
| Alpha | Bravo |
| Alpha | Charlie |
| Delta | Charlie |
| Delta | Echo |
| Delta | Echo |
| Mike | Rodeo |
想要通过loc方法,基于Col1列的每个值,将Col2列中所有匹配的值生成列表,作为新增列Col3的内容。
尝试了以下代码,但Col3仅能获取到Col2的单个值,而非完整列表;但单独运行代码右侧针对特定值的部分时,能返回正确的列表:
for value in col1_values: df.loc[df['Col1'].eq(value),'Col3'] = list(df['Col2'].loc[df['Col1'].eq(value)])
解决方案
方法1:使用groupby + transform(推荐)
这是更简洁高效的Pandas原生方法,无需手动循环:
df['Col3'] = df.groupby('Col1')['Col2'].transform(list)
运行后得到的目标结果:
| Col1 | Col2 | Col3 |
|---|---|---|
| Alpha | Bravo | ['Bravo', 'Charlie'] |
| Alpha | Charlie | ['Bravo', 'Charlie'] |
| Delta | Charlie | ['Charlie', 'Echo', 'Echo'] |
| Delta | Echo | ['Charlie', 'Echo', 'Echo'] |
| Delta | Echo | ['Charlie', 'Echo', 'Echo'] |
| Mike | Rodeo | ['Rodeo'] |
方法2:修改原有循环代码
原代码的问题在于:直接给loc选中的行赋值列表时,Pandas会将列表广播到每一行,即列表的第n个元素对应选中的第n行,而非把整个列表作为单个单元格的值。
修改方式是把列表包装成嵌套列表,确保每个单元格都能接收完整列表:
col1_values = df['Col1'].unique() for value in col1_values: target_list = list(df['Col2'].loc[df['Col1'].eq(value)]) # 生成与选中行数量一致的嵌套列表,避免广播 df.loc[df['Col1'].eq(value), 'Col3'] = [target_list] * len(df[df['Col1'].eq(value)])
也可以用apply直接生成:
df['Col3'] = df['Col1'].apply(lambda x: list(df[df['Col1'] == x]['Col2']))
内容的提问来源于stack exchange,提问作者Stephen Juza
相关产品推荐
相关产品推荐

