在使用apply
的Pandas数据框上调用axis=1
时,在尝试将列表设置为单元格值时获取ValueError
。
注意:不同行中的列表长度各不相同,这似乎是原因,但不确定如何克服它。
import numpy as np
import pandas as pd
data = [{'a': 1, 'b': '3412', 'c': 0}, {'a': 88, 'b': '56\t23', 'c': 1},
{'a': 45, 'b': '412\t34\t324', '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 56\t23 1 [0, 0]
2 45 412\t34\t324 2 [3, 3, 6]
get_rank_list
在产生上述预期结果时有效但不是get_rank_array
。
我理解(3,)形状来自数据框中的列数,(2,)来自第二行中分割56\t23
后列表的长度。
但我不明白错误背后的原因。
何时
data = [{'a': 45, 'b': '412\t34\t324', 'c': 2},
{'a': 1, 'b': '3412', 'c': 0}, {'a': 88, 'b': '56\t23', 'c': 1}]
列表也会出错。
答案 0 :(得分:2)
观察 -
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
Pandas在apply
内做了两件事:
np.array
和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)
简而言之,这是大熊猫内部的结果。有关详细信息,请仔细阅读apply
function code on GitHub。
要获得所需的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 56\t23 1 [4, 2]
2 45 412\t34\t324 2 [9, 0, 3]