我有一个数据框,其中一列包含值列表,例如
dict = {'a' : [0, 1, 2], 'b' : [4, 5, 6]}
df = pd.DataFrame(dict)
df.loc[:, 'c'] = -1
df['c'] = df.apply(lambda x: [x.a, x.b], axis=1)
所以我得到了:
a b c
0 0 4 [0, 4]
1 1 5 [1, 5]
2 2 6 [2, 6]
我现在想在新列d中保存列c的每个条目的最小值,这应该给我以下数据框:
a b c d
0 0 4 [0, 4] 0
1 1 5 [1, 5] 1
2 2 6 [2, 6] 2
虽然我总是不能用min()或类似的方法做到这一点。现在我正在使用df.apply(lambda x:min(x [' c'],轴= 1)。但在我的情况下这太慢了。你知道更快的方法吗? ? 谢谢!
答案 0 :(得分:3)
你可以从numpy获得帮助:
import numpy as np
df['d'] = np.array(df['c'].tolist()).min(axis=1)
如评论中所述,如果您不需要列c
,那么:
df['d'] = df[['a','b']].min(axis=1)
答案 1 :(得分:2)
请记住,系列(如df['c']
)是可迭代的。然后,您可以创建一个新列表并将其设置为键,就像您使用字典一样。该列表将自动转换为pd.Series
对象。除非您正在处理真正(非常)大数据,否则无需使用花哨的pandas
函数。
df['d'] = [min(c) for c in df['c']]
编辑:更新以下评论
df['d'] = [min(c, key=lambda v: v - df.a) for c in df['c']]
这不起作用,因为v
是一个值(在第一次迭代中传递0
,然后传递4
)。 df.a
是一个系列。 v - df.a
是一个包含元素[v - df.a[0], v - df.a[1], ...]
的新系列。然后min
尝试比较这些系列键,这没有任何意义,因为它将测试if True, False, ...]
或类似pandas
引发错误的那些,因为它不会真有意义。你需要的是
df['d'] = [min(c, key=lambda v: v - df['a'][i]) for i, c in enumerate(df['c'])]
# I prefer to use df['a'] rather than df.a
所以你依次从df['a']
,而不是整个系列v
获取df['a']
的每个值。
然而,在计算最小值时取一个常数绝对没有任何作用,但我猜这是从你实际做的那里简化的。上面的两个样本将完全相同。
答案 2 :(得分:2)
这是一个功能性解决方案。
df['d'] = list(map(min, df['c']))
它的工作原因是:
df['c']
是pd.Series
,是一个可迭代的对象。map
是一个惰性运算符,它将函数应用于iterable的每个元素。map
是懒惰的,我们必须应用list
才能分配系列。