Pandas非零值列合并为列表及列表排序报错排查
Pandas数据处理问题及报错排查
问题1:提取每行非零值组成列表
我有如下Pandas数据框:
mwe5a = pd.DataFrame({'a': [0.1, 0.0], 'b': [0.0, 0.2], 'c': [0.3, 0.0] } )
输出:
a b c 0 0.1 0.0 0.3 1 0.0 0.2 0.0
期望得到:
output_column 0 [0.1, 0.3] 1 [0.2]
实现方法:
使用apply逐行过滤非零值,再转成DataFrame:
mwe5b = mwe5a.apply(lambda row: list(row[row != 0]), axis=1).to_frame('output_column')
问题2:根据对应数值排序列表元素
接下来,需要根据上述得到的数值,将另一个DataFrame的列表元素按从大到小排序:
mwe7a = pd.DataFrame({'items': [ ['item1', 'item2'], ['item3'] ]})
输出:
items 0 ['item1', 'item2'] 1 ['item3']
期望结果:
items 0 ['item2', 'item1'] 1 ['item3']
结合问题1的结果,实现排序的核心逻辑是将items列表中的元素与output_column的数值一一对应,按数值倒序排序:
# 先得到问题1的结果mwe5b mwe7b = mwe7a.apply(lambda x: sorted(x['items'], key=lambda y: mwe5b.loc[x.name, 'output_column'][x['items'].index(y)], reverse=True), axis=1).to_frame('items')
更新:测试代码正常但实际数据报错
我更新了测试数据避免混淆,以下测试代码可正常运行:
token_uniqueness_sparse = pd.DataFrame({'token_a': [0.1, 0.0], 'token_b': [0.0, 0.2], 'token c': [0.3, 0.0] } ) sf_fake = pd.DataFrame({'items': [ ['token_a', 'token_c'], ['token_b']], 'rcol': [1,2] }) # 生成非零值列表 token_uniqueness_dense = (token_uniqueness_sparse .apply(lambda x: list(x[x.ne(0)]), axis=1) .to_frame('output_column')) # 按对应数值排序items sf_fake.apply(lambda x: sorted(x['items'], key=lambda y: token_uniqueness_dense.loc[x.name, 'output_column'][x['items'].index(y)], reverse=True), axis=1)
但将该方法应用到实际数据时,出现IndexError: list index out of range错误:
Input In [76], in <lambda>(x) ----> 1 (forbes_df.apply(lambda x: sorted(x['tokenized_company_name'], 2 key=lambda y: tfidf_df_dense.loc[x.name, 3 'output_column'][x['tokenized_company_name'].index(y)], reverse=True), axis=1)) Input In [76], in <lambda>.<locals>.<lambda>(y) 1 (forbes_df.apply(lambda x: sorted(x['tokenized_company_name'], ----> 2 key=lambda y: tfidf_df_dense.loc[x.name, 3 'output_column'][x['tokenized_company_name'].index(y)], reverse=True), axis=1)) IndexError: list index out of range
实际数据样例:
samp = pd.DataFrame({'tokens': [['berkshire', 'hathaway'], ['icbc'], ['saudi', 'arabian', 'oil', 'company', 'saudi', 'aramco'], ['jpmorgan', 'chase'], ['china', 'construction', 'bank'], [] ]}) imp = pd.DataFrame({'importance': [[0.7071067811865476, 0.7071067811865476], [1.0], [0.3779598156018814, 0.39838548612653973, 0.39838548612653973, 0.3285496573358837, 0.6570993146717674], [0.7071067811865476, 0.7071067811865476], [0.4225972188244829, 0.510750779645552, 0.7486956870005814], [] ]})
报错排查方向
- 检查行列索引匹配:确认
forbes_df和tfidf_df_dense的行索引完全一致,比如是否存在索引缺失、类型不匹配(整数/字符串索引混用)的情况,导致tfidf_df_dense.loc[x.name]取到的列表长度和tokenized_company_name的长度不匹配。 - 处理重复元素的索引问题:当
tokenized_company_name中有重复元素(比如样例里的'saudi'),index(y)只会返回第一个匹配项的位置,但如果对应importance列表的长度和tokens列表长度一致,重复元素对应的重要性位置和index(y)返回的位置不对应,会导致索引越界。 - 验证列表长度一致性:逐行检查
tokenized_company_name的长度是否和对应output_column的长度完全一致,比如是否存在某行tokens列表长度为N,但重要性列表长度不为N的情况,这会让index(y)返回的索引超出重要性列表范围。 - 空列表处理:当
tokenized_company_name是空列表时,虽然sorted不会报错,但如果对应output_column也是空列表,后续索引操作可能触发错误,需要提前过滤或处理空行。 - 替换索引查找为映射关系:不用
index(y)定位,而是提前为每行建立tokens和重要性的字典映射,比如dict(zip(tokens_list, importance_list)),排序时直接取字典中的值,既解决重复元素问题,也能避免索引越界。
内容的提问来源于stack exchange,提问作者user2205916
相关产品推荐
相关产品推荐

