python 使用可迭代对象设置时,必须具有相等的len键和值

zxlwwiss  于 2022-12-02  发布在  Python
关注(0)|答案(2)|浏览(355)

I have two dataframes as follows:
leader :

0 11
1  8
2  5
3  9
4  8
5  6
[6065 rows x 2 columns]
```none
`DatasetLabel`:
```none
   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]

The Information dataset column names 0 to 6 are DatasetLabel about data and 7 to 12 are indexes that refer to the first column of leader Dataframe.
I want to create dataset where instead of the indexes in DatasetLabel dataframe, I have the value of each index from the leader dataframe, which is leader.iloc[index,1]
How can I do it using python features?
The output should look like:
DatasetLabel :

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

I have come up with the following, but I get an error:

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

Error:

ValueError: Must have equal len keys and value when setting with an iterable
idfiyjo8

idfiyjo81#

可以使用applyleader进行索引,并与DatasetLabel交换值,尽管这不是很好。
一个问题是Pandas不允许我们使用NaN进行索引。转换为str提供了一个解决方案。(因为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

leader为:

0   1
0  0  11
1  1   8
2  2   5
3  3   9
4  4   8
5  5   6

然后道:

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

现在,我们可以使用updated对未修改的列(我们称之为original)进行concat

original_cols = DatasetLabel.columns[~DatasetLabel.columns.isin(cols)]
original = DatasetLabel[original_cols]
pd.concat([original, updated], axis=1)

输出量:

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

注意:这里使用concat可能会更清楚,但这里有另一种更清楚的合并originalupdated的方法,使用assign

DatasetLabel.assign(**updated)
irlmq6kh

irlmq6kh2#

源代码显示,当你试图将一个类似列表的对象(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]
    • 解决方案:**复制列表/数组/元组,转置它(使用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'])))

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]
    • 解决方案:**要使其按预期工作,必须将列表/数组转换为具有正确索引的Series:
df.loc[[0, 1], ['A', 'B', 'C']] = pd.Series([100, 200.2], index=[0, 1])

一种常见的子情况是行索引来自布尔掩码。注意:OP中就是这种情况。在这种情况下,只需使用掩码过滤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

1.* * 您想要在一个数据行的某些数据列中储存相同的清单。**此案例的说明如下:

    • 解决方案:**使用正确的索引显式构造Series。
# 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]])

1:在这里,我们试图将一个包含float的列表赋给int dtype列,这导致了这个错误。如果我们试图赋给一个int列表(这样dtype匹配),我们会得到一个不同的错误:ValueError: shape mismatch: value array of shape (2,) could not be broadcast to indexing result of shape (2,3),其也可以通过与上述相同的方法来求解。
2:如果被赋值的对象是一个numpy数组,并且形状不匹配,就会发生与ValueError: Must have equal len keys and value when setting with an ndarray相关的错误。这个错误通常可以使用np.tile或者简单地转置数组来解决。

相关问题