设置可迭代项时必须具有相等的len键和值

use*_*649 2 python pandas

我有两个数据框作为流:

leader:
    0 11
    1 8
    2 5
    3 9
    4 8
    5 6
    [6065 rows x 2 columns]

DatasetLabel:    
    Unnamed: 0      0    1  ....    7     8    9  10  11  12  
    0               A    J  ....    1     2    5 NaN NaN NaN  
    1               B    K  ....    3     4   NaN  NaN NaN NaN  

    [4095 rows x 14 columns]
Run Code Online (Sandbox Code Playgroud)

信息数据集的列名称0到6是关于数据的DatasetLabel,而7到12是引用领导者Dataframe的第一列的索引。

我想创建一个数据集,而不是DatasetLabel Dataset中的索引,而是从leader数据集中获取每个索引的值,即 leader.iloc[index,1]

我该如何使用python功能?

输出应如下所示:

 DatasetLabel:    
        Unnamed: 0      0    1  ....    7     8    9  10  11  12  
        0               A    J  ....    8     5    6 NaN NaN NaN  
        1               B    K  ....    9     8   NaN  NaN NaN NaN  
Run Code Online (Sandbox Code Playgroud)

我提出了以下建议,但出现错误:

    for column in DatasetLabel.ix[:,8:13]:
        DatasetLabel[DatasetLabel[column].notnull ()]=leader.iloc[DatasetLabel[DatasetLabel[column].notnull ()][column].values,1]
Run Code Online (Sandbox Code Playgroud)

错误:

ValueError: Must have equal len keys and value when setting with an iterable
Run Code Online (Sandbox Code Playgroud)

cot*_*ail 7

代码显示,当您尝试将类似列表的对象(numpy 数组、列表、集合、元组等)广播到多个列或多行但未正确指定索引时,会发生此错误。当然,类似列表的对象没有像 pandas 对象那样的自定义索引,因此通常会导致此错误。

常见情况解决方案:

  1. 您希望一次在多个列中分配相同的值。换句话说,您想要使用类似列表的对象更改某些列的值,该对象的 (a) 长度与列数或行数不匹配,并且 (b) dtype 与它们所在列的 dtype 不匹配被分配给. 1一个例子可能会更清楚。如果您尝试进行以下转换:

    第一的

    使用类似于下面的代码,会出现此错误:

    df = pd.DataFrame({'A': [1, 5, 9], 'B': [2, 6, 10], 'C': [3, 7, 11], 'D': [4, 8, 12]})
    df.loc[:2, ['C','D']] = [100, 200.2, 300]
    
    Run Code Online (Sandbox Code Playgroud)

    解决方案:复制列表/数组/元组,转置它(使用Tzip())并分配给相关的行/列。2

    df.loc[:2, ['C','D']] = np.tile([100, 200.2, 300], (len(['C','D']), 1)).T 
    # if you don't fancy numpy, use zip() on a list
    # df.loc[:2, ['C','D']] = list(zip(*[[100, 200.2, 300]]*len(['C','D'])))
    
    Run Code Online (Sandbox Code Playgroud)

  1. 您想要一次将相同的值分配给多行。如果你尝试进行以下改造

    第二

    使用类似于以下的代码:

    df = pd.DataFrame({'A': [1, 5, 9], 'B': [2, 6, 10], 'C': [3, 7, 11], 'D': [4, 8, 12]})
    df.loc[[0, 1], ['A', 'B', 'C']] = [100, 200.2]
    
    Run Code Online (Sandbox Code Playgroud)

    解决方案:为了使其按预期工作,我们必须将列表/数组转换为具有正确索引的系列:

    df.loc[[0, 1], ['A', 'B', 'C']] = pd.Series([100, 200.2], index=[0, 1])
    
    Run Code Online (Sandbox Code Playgroud)

    常见的子情况是行索引是否来自使用布尔掩码。NB 这是OP中的情况。在这种情况下,只需使用 mask 进行过滤即可df.index

    msk = df.index < 2
    df.loc[msk, ['A', 'B', 'C']] = [100, 200.2]                                 # <--- error
    df.loc[msk, ['A', 'B', 'C']] = pd.Series([100, 200.2], index=df.index[msk]) # <--- OK
    
    Run Code Online (Sandbox Code Playgroud)

  1. 您希望将相同的列表存储在列的某些行中。这个案例的一个例子是:

    第三

    解决方案:显式构造一个具有正确索引的系列。

    # for the case on the left in the image above
    df['D'] = pd.Series([[100, 200.2]]*len(df), index=df.index)
    
    # latter case
    df.loc[[1], 'D'] = pd.Series([[100, 200.2]], index=df.index[[1]])
    
    Run Code Online (Sandbox Code Playgroud)

1:在这里,我们尝试将包含 float 的列表分配给 int dtype 列,这导致了此错误的发生。如果我们尝试分配一个整数列表(以便数据类型匹配),我们会得到一个不同的错误:ValueError: shape mismatch: value array of shape (2,) could not be broadcast to indexing result of shape (2,3)也可以通过与上面相同的方法来解决。

ValueError: Must have equal len keys and value when setting with an ndarray2:如果分配的对象是 numpy 数组并且形状不匹配,则会发生与此相关的错误。这个问题通常可以使用数组np.tile或简单地转置数组来解决。


and*_*ece 5

您可以使用apply索引leader和与交换值DatasetLabel,尽管它不是很漂亮。

一个问题是熊猫不允许我们索引NaN。转换为str提供了一种解决方法。但这产生了第二个问题,即column 9为type float(因为NaNfloat),因此5变为5.0。一旦是字符串,即为"5.0",将无法匹配中的索引值leader。我们可以删除.0,然后此解决方案将起作用-但这有点麻烦。

带有DatasetLabel

   Unnamed:0  0  1  7  8    9  10  11  12
0          0  A  J  1  2  5.0 NaN NaN NaN
1          1  B  K  3  4  NaN NaN NaN NaN
Run Code Online (Sandbox Code Playgroud)

leader作为:

   0   1
0  0  11
1  1   8
2  2   5
3  3   9
4  4   8
5  5   6
Run Code Online (Sandbox Code Playgroud)

然后:

cols = ["7","8","9","10","11","12"]
updated = DatasetLabel[cols].apply(
    lambda x: leader.loc[x.astype(str).str.split(".").str[0], 1].values, axis=1)

updated
     7    8    9  10  11  12
0  8.0  5.0  6.0 NaN NaN NaN
1  9.0  8.0  NaN NaN NaN NaN
Run Code Online (Sandbox Code Playgroud)

现在,我们可以使用concat以下命令修改未修改的列(称为originalupdated

original_cols = DatasetLabel.columns[~DatasetLabel.columns.isin(cols)]
original = DatasetLabel[original_cols]
pd.concat([original, updated], axis=1)
Run Code Online (Sandbox Code Playgroud)

输出:

   Unnamed:0  0  1    7    8    9  10  11  12
0          0  A  J  8.0  5.0  6.0 NaN NaN NaN
1          1  B  K  9.0  8.0  NaN NaN NaN NaN
Run Code Online (Sandbox Code Playgroud)

注意:concat在这里使用可能更清晰,但是这是使用original和合并的另一种更简洁的方法:updatedassign

DatasetLabel.assign(**updated)
Run Code Online (Sandbox Code Playgroud)