我有一个pandas DataFrame,其中包含一些数组列。建议通过不同的位置索引为这些列中的一些建立索引的方法是什么?例如,从名为l
的数组列中,我需要第二个元素,从名为a
的数组列中,我需要第一个元素。结果应该是一个新的DataFrame。数组列可以包含Python列表或Numpy数组,但这可能无关紧要。
我有三个解决方案,但我真的不喜欢其中任何一个。
df= pd.DataFrame({'l': [[1, 2, 4], [3, 2, 0, 10]], \
'a':[np.array(["foo", "bar", "baz"]), np.array(["qux", "quux"])], \
'dontcare': [10, 20]})
l a dontcare
0 [1, 2, 4] [foo, bar, baz] 10
1 [3, 2, 0, 10] [qux, quux] 20
解决方案1,带有str
和join
df['l'].str[1].to_frame('l').join(df['a'].str[0])
l a
0 2 foo
1 2 qux
解决方案2,具有功能apply
并创建系列
df.apply(lambda row: pd.Series([row['l'][1], row['a'][0]], index=['l', 'a']), axis=1)
解决方案3,带有apply
和broadcast
。
df[['l', 'a']].apply(lambda row: [row['l'][1], row['a'][0]], axis=1, result_type='broadcast')
我们可以假设输出列名称与输入列名称匹配,并且我们不需要任何数组列中的多个元素。
答案 0 :(得分:1)
我认为这取决于。
第一个解决方案是最通用的,如果索引不存在,则始终工作-然后返回NaN
s。但是如果DataFrame
大,这也是解决方案速度最慢的原因。
print (df['l'].str[3].to_frame('l').join(df['a'].str[2]))
l a
0 NaN baz
1 10.0 NaN
使用apply
的另一种解决方案应该更快,但如果值不存在,则会失败。
print (df.apply(lambda row: pd.Series([row['l'][3], row['a'][2]], index=['l', 'a']), axis=1))
IndexError :(“列表索引超出范围”,“发生在索引0”)
如果列表中的值始终存在,则另一种想法是使用列表理解(但失败,类似套用,如果不存在,则失败)与tail一起使用*c
:
df= pd.DataFrame({'l': [[1, 2, 4], [3, 2, 0, 10]], \
'a':[np.array(["foo", "bar", "baz"]), np.array(["qux", "quux"])], \
'dontcare': [10, 20],
's': [10, 20],
'b': [10, 20]})
print (df)
l a dontcare s b
0 [1, 2, 4] [foo, bar, baz] 10 10 10
1 [3, 2, 0, 10] [qux, quux] 20 20 20
df = pd.DataFrame([(a[1], b[0]) for a,b, *c in df.values], columns=['l', 'a'])
print (df)
l a
0 2 foo
1 2 qux
或通过list
选择列进行处理:
df = pd.DataFrame([(a[1], b[0]) for a,b in df[['l','a']].values], columns=['l', 'a'])