使用axis = 1调用apply并将不同长度的列表设置为cell-value时的Pandas ValueError

时间:2018-03-23 17:29:05

标签: python pandas numpy dataframe apply

在使用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}]

列表也会出错。

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内做了两件事:

  1. 特殊情况np.arraylist s以及
  2. 如果形状兼容,它会尝试将结果捕捉到DataFrame中
  3. 请注意,数组与列表的区别有点不同,其中,如果形状不兼容,对于列表,结果是一系列(如上面第二个输出所示),但是对于数组,

    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]