我有一个Pandas DataFrame,其中包含一个2D数组作为列,如下所示:
Name 2DValueList
item 1 [ [ 0.0, 1.0 ], [ 0.0, 6.0 ], [ 0.0, 2.0 ] ]
item 2 [ [ 0.0, 2.0 ], [ 0.0, 1.0 ], [ 0.0, 1.0 ] ]
item 3 [ [ 0.0, 1.0 ], [ 0.0, 3.0 ], [ 0.0, 5.0 ], [ 0.0, 1.0 ] ]
item 4
item 5 [ [ 0.0, 4.0 ], [ 0.0, 1.0 ], [ 0.0, 2.0 ] ]
第一个值与这个问题无关,因此我将它们都设置为0。我只对第二个值感兴趣。还要注意,配对的数量可以变化或为空。
我希望能够制作一个仅包含数组中顶部(最大) n 个元素的新数据框。
前2个元素看起来像这样:
Name 2DValueList
item 1 [ [ 0.0, 6.0 ], [ 0.0, 2.0 ] ]
item 2 [ [ 0.0, 2.0 ], [ 0.0, 1.0 ] ]
item 3 [ [ 0.0, 5.0 ], [ 0.0, 3.0 ] ]
item 4
item 5 [ [ 0.0, 4.0 ], [ 0.0, 2.0 ] ]
我会在最大的情况下使用pandas,但是我不确定如何使其接受2D数组的列。
实际上,二维数组包含数千个值对,并且有成千上万的行。我愿意采用更好的方法来保存这些数据,这些数据将更加通用。
答案 0 :(得分:1)
如果2DValueList
的每个单元格都是列表列表,那么有效的方法是将heapq.nlargest
与itemgetter
一起使用,并结合列表理解
from heapq import nlargest
from operator import itemgetter
df['new_list'] = [nlargest(2, x, key=itemgetter(1)) for x in df['2DValueList']]
Out[119]:
Name 2DValueList new_list
0 item 1 [[0, 1], [0, 6], [0, 2]] [[0, 6], [0, 2]]
1 item 2 [[0, 2], [0, 1], [0, 1]] [[0, 2], [0, 1]]
2 item 3 [[0, 1], [0, 3], [0, 5]] [[0, 5], [0, 3]]
3 item 4 [[0, 4], [0, 1], [0, 2]] [[0, 4], [0, 2]]
如果每个单元格都是一个numpy 2darray,则上述方法仍然可以正常工作。但是,我认为使用numpy argsort
会更好
df['new_list'] = [x[np.argsort(-x, axis=0)[:2,1]] for x in df['2DValueList']]
Out[128]:
Name 2DValueList new_list
0 item 1 [[0, 1], [0, 6], [0, 2]] [[0, 6], [0, 2]]
1 item 2 [[0, 2], [0, 1], [0, 1]] [[0, 2], [0, 1]]
2 item 3 [[0, 1], [0, 3], [0, 5]] [[0, 5], [0, 3]]
3 item 4 [[0, 4], [0, 1], [0, 2]] [[0, 4], [0, 2]]
最后,如果不需要排序后的前n个最大子数组,argpartition
会比argsort
快
答案 1 :(得分:0)
import ast
df['2DValueList'] = df['2DValueList'].apply(ast.literal_eval).apply(lambda x: sorted(x,reverse=True)[:2])
Name 2DValueList
0 item 1 [[0, 6], [0, 2]]
1 item 2 [[0, 2], [0, 1]]
2 item 3 [[0, 5], [0, 3]]
3 item 4 [[0, 4], [0, 2]]