使用 axis=1
在 Pandas 数据帧上调用 apply
时,尝试将列表设置为单元格值时ValueError
。
注意:不同行中的列表长度不同,这似乎是原因,但不确定如何克服它。
import numpy as np
import pandas as pd
data = [{'a': 1, 'b': '3412', 'c': 0}, {'a': 88, 'b': '56t23', 'c': 1},
{'a': 45, 'b': '412t34t324', 'c': 2}]
df = pd.DataFrame.from_dict(data)
print("df: ")
print(df)
def get_rank_array(ids):
ids = list(map(int, ids))
return np.random.randint(0, 10, len(ids))
def get_rank_list(ids):
ids = list(map(int, ids))
return np.random.randint(0, 10, len(ids)).tolist()
df['rank'] = df.apply(lambda row: get_rank_array(row['b'].split('t')), axis=1)
ValueError: could not broadcast input array from shape (2) into shape (3)
df['rank'] = df.apply(lambda row: get_rank_list(row['b'].split('t')), axis=1)
print("df: ")
print(df)
df:
a b c rank
0 1 3412 0 [6]
1 88 56t23 1 [0, 0]
2 45 412t34t324 2 [3, 3, 6]
get_rank_list
有效,但在产生上述预期结果方面没有get_rank_array
。
我知道 (3,( 形状来自数据框中的列数,(2,( 来自在第二行拆分56t23
后的列表长度。但我不明白错误本身背后的原因。
什么时候
data = [{'a': 45, 'b': '412t34t324', 'c': 2},
{'a': 1, 'b': '3412', 'c': 0}, {'a': 88, 'b': '56t23', 'c': 1}]
列表也会发生错误。
观察 -
df.apply(lambda x: [0, 1, 2])
a b c
0 0 0 0
1 1 1 1
2 2 2 2
df.apply(lambda x: [0, 1])
a [0, 1]
b [0, 1]
c [0, 1]
dtype: object
熊猫在apply
里面做了两件事:
- 它的特殊情况
np.array
s 和list
s,以及 - 如果形状兼容,它会尝试将结果对齐到数据帧中
的特殊情况与列表略有不同,因为如果形状不兼容,对于列表,结果是一个系列(如上面的第二个输出所示(,但对于数组,
df.apply(lambda x: np.array([0, 1, 2]))
a b c
0 0 0 0
1 1 1 1
2 2 2 2
df.apply(lambda x: np.array([0, 1]))
ValueError: Shape of passed values is (3, 2), indices imply (3, 3)
简而言之,这是熊猫内部的结果。有关详细信息,请仔细阅读 GitHub 上的apply
函数代码。
要获得所需的 o/p,请使用列表推导并将结果分配给 df['new']
。不要使用应用。
df['new'] = [
np.random.randint(0, 10, len(x.split('t'))).tolist() for x in df.b
]
df
a b c new
0 1 3412 0 [8]
1 88 56t23 1 [4, 2]
2 45 412t34t324 2 [9, 0, 3]