When running the example code below I get a
ValueError: cannot set using a multi-index selection indexer with a different
length than the value
The error is raised upon execution of
df.loc[(9, 0), ("clouds", "type")] = np.array([None, None])
here:
~\Anaconda3\lib\site-packages\pandas\core\indexing.py in _setitem_with_indexer(self, indexer, value)
492
493 if len(obj[idx]) != len(value):
--> 494 raise ValueError
The problem seems to be connected to writing a numpy array to a "cell" of the dataframe. It seems that obj[idx] refers to index (20,) in the dataframe, while it should refer to (9,0). A few iterations before the one that raises the error, when executing
df.loc[(6, 0), ("clouds", "type")] = np.array([None, None])
no error is raised as by coincidence obj[idx] refers to index (17,) in the dataframe which has 2 sub-indices, so that by chance len(obj[idx])==len(value)==2.
Remark:
When I read
df.loc[(9, 0), ("clouds", "type")].values
it correctly returns [104].
Question:
Am I using the .loc function incorrectly? Am I doing something else wrong? Or is this a problem within pandas? How could I avoid it?
I greatly appreciate any help as the problem got me stuck for a few days now :/
Code:
import pandas as pd
import numpy as np
mi = pd.MultiIndex(levels=[[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22],
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12]],
labels=[[0, 0, 1, 1, 1, 1, 2, 2, 2, 3, 3, 3, 3, 3, 3, 4, 5, 6, 7, 8, 9, 10, 10, 11, 12, 12, 13, 14, 14,
14, 15, 16, 17, 17, 18, 18, 18, 19, 19, 19, 19, 20, 20, 20, 21, 21, 21, 22, 22, 22],
[0, 1, 0, 1, 2, 3, 0, 1, 2, 0, 1, 2, 3, 4, 5, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 1, 2, 0, 0,
0, 1, 0, 1, 2, 0, 1, 2, 3, 0, 1, 2, 0, 1, 2, 0, 1, 2]])
mc = pd.MultiIndex(levels=[['clouds', 'group', 'header', 'vertical_visibility', 'visibility', 'weather', 'wind', 'windshear'],
['', 'BR', 'DS', 'DU', 'DZ', 'FC', 'FG', 'FU', 'GR', 'GS', 'HZ', 'IC', 'PL', 'PO', 'PY', 'RA', 'SA', 'SG', 'SN', 'SQ', 'SS', 'UP', 'VA', 'altitude', 'ceiling', 'direction', 'form', 'from_date', 'from_hours', 'from_minutes', 'gust', 'icao_code', 'layer', 'more', 'origin_date', 'origin_hours', 'origin_minutes', 'probability', 'range', 'speed', 'till_date', 'till_hours', 'till_minutes', 'type', 'unit', 'valid_from_date', 'valid_from_hours', 'valid_till_date', 'valid_till_hours'],
['bool', 'intensity', 'modifier']],
labels=[[0, 0, 0, 1, 1, 1],
[24, 32, 43, 27, 28, 29],
[-1, -1, -1, -1, -1, -1]])
arr = np.array(range(0,len(mi)*len(mc))).reshape(len(mi),len(mc))
df = pd.DataFrame(arr, index=mi, columns=mc)
values = {0: {0: [None]}, 1: {0: [None], 1: [None], 2: [None], 3: [None]}, 2: {0: [None], 2: [None]}, 3: {0: [None], 1: [None], 2: [None], 3: [None], 4: [None], 5: [None]}, 4: {0: [None]}, 6: {0: [None, None]}, 9: {0: [None, None]}}
for i, val in values.items():
for j, v in val.items():
df.loc[(i,j),("clouds", "type")] = np.array(v)