Можно ли объединить один уровень и другой многоуровневый фрейм данных и иметь по оси 1 один уровень и многоуровневый одновременно?(Панды) - PullRequest
0 голосов
/ 25 октября 2018

У меня есть этот одноуровневый фрейм данных:

d = {'A': np.random.randint(0, 10, 5)
   , 'B': np.random.randint(0, 10, 5)
   , 'C': np.random.randint(0, 10, 5)
   , 'D': np.random.randint(0, 10, 5)}
x = pd.DataFrame(d)
print(x)

   A  B  C  D
0  8  7  6  0
1  6  5  4  9
2  4  0  5  7
3  1  9  7  9
4  6  9  9  8

И этот многоуровневый :

from functools import reduce

v = ['u','v','z']
l = ['300','350','400','450','500'] * len(v)
d = ['1','2','3','4'] * len(l)

size = len(v) * len(l) * len(d)

der_v = reduce(lambda x,y: x+y, [[i] * 20 for i in v])
der_l = reduce(lambda x,y: x+y, [[i] * 4 for i in l])
der_d = reduce(lambda x,y: x+y, [[i] for i in d])

arrays =[der_v,der_l,der_d]

y = pd.DataFrame(np.random.randint(0, 1, (5,60)),index=range(0,5), columns=arrays)
print(y)

    u                              ...   z                             
  300          350          400    ... 400    450          500         
    1  2  3  4   1  2  3  4   1  2 ...   3  4   1  2  3  4   1  2  3  4
0   0  0  0  0   0  0  0  0   0  0 ...   0  0   0  0  0  0   0  0  0  0
1   0  0  0  0   0  0  0  0   0  0 ...   0  0   0  0  0  0   0  0  0  0
2   0  0  0  0   0  0  0  0   0  0 ...   0  0   0  0  0  0   0  0  0  0
3   0  0  0  0   0  0  0  0   0  0 ...   0  0   0  0  0  0   0  0  0  0
4   0  0  0  0   0  0  0  0   0  0 ...   0  0   0  0  0  0   0  0  0  0

[5 rows x 60 columns]

Я пытаюсь объяснить:

z = pd.concat([x, y], axis=1)

Итак, я получил вот так:

  A  B  C  D  (u, 300, 1)  (u, 300, 2)  (u, 300, 3)  (u, 300, 4)  \
0  8  7  6  0            0            0            0            0   ...
1  6  5  4  9            0            0            0            0   ...
2  4  0  5  7            0            0            0            0   ...
3  1  9  7  9            0            0            0            0   ...
4  6  9  9  8            0            0            0            0   ...

Но я получил столбцы в виде кортежей, например: (u, 300, 1).Это странно! Возможно ли иметь по оси 1 один уровень и многоуровневый одновременно?

Ожидаемый результат:

                u                              ...   z                             
   A  B  C  D  300          350          400    ... 400    450          500         
               1  2  3  4   1  2  3  4   1  2 ...   3  4   1  2  3  4   1  2  3  4
0  8  7  6  0  0  0  0  0   0  0  0  0   0  0 ...   0  0   0  0  0  0   0  0  0  0
1  6  5  4  9  0  0  0  0   0  0  0  0   0  0 ...   0  0   0  0  0  0   0  0  0  0
2  4  0  5  7  0  0  0  0   0  0  0  0   0  0 ...   0  0   0  0  0  0   0  0  0  0
3  1  9  7  9  0  0  0  0   0  0  0  0   0  0 ...   0  0   0  0  0  0   0  0  0  0
4  6  9  9  8  0  0  0  0   0  0  0  0   0  0 ...   0  0   0  0  0  0   0  0  0  0

Я действительно не знаю, были ли возможны столбцы содин уровень и многоуровневый.Так что, надеюсь, удастся нарезать ломтиками.Например: y.loc [:, ('u', '500')] работает нормально.Но после конкататации больше не работает.

1 Ответ

0 голосов
/ 27 октября 2018

Я решаю без сцепления, потому что не возможно иметь по оси 1 разные уровни.Я решил использовать данные в фрейме данных x как индекс в фрейме данных y.

Итак, выполните следующие действия:

1. Создайте фрейм данных x:

d = {'A': np.random.randint(0, 10, 5)
   , 'B': np.random.randint(0, 10, 5)
   , 'C': np.random.randint(0, 10, 5)
   , 'D': np.random.randint(0, 10, 5)}
x = pd.DataFrame(d)

   A  B  C  D
0  7  1  6  8
1  4  0  5  6
2  7  5  0  7
3  8  4  3  8
4  9  1  4  0

2.Создание индекса на основе фрейма данных x:

index = [x[col] for col in x.columns]

3. Создание существ для фрейма данных y:

from functools import reduce

v = ['u','v','z']
l = ['300','350','400','450','500'] * len(v)
d = ['1','2','3','4'] * len(l)

size = len(v) * len(l) * len(d)

der_v = reduce(lambda x,y: x+y, [[i] * 20 for i in v])
der_l = reduce(lambda x,y: x+y, [[i] * 4 for i in l])
der_d = reduce(lambda x,y: x+y, [[i] for i in d])

arrays =[der_v,der_l,der_d]

4. Теперь, чтобы создать фрейм данных y, мы используем индекс изх в качестве параметра:

y = pd.DataFrame(np.random.randint(0, 1, (5,60)), columns=arrays, index=index)
y.columns = y.columns.rename(['variables', 'level','days'], level=[0,1,2])
y.index.names = ['A','B','C','D']
print(y)

variables   u                              ...   z                            \
level     300          350          400    ... 400    450          500         
days        1  2  3  4   1  2  3  4   1  2 ...   3  4   1  2  3  4   1  2  3   
A B C D                                    ...                                 
7 1 6 8     0  0  0  0   0  0  0  0   0  0 ...   0  0   0  0  0  0   0  0  0   
4 0 5 6     0  0  0  0   0  0  0  0   0  0 ...   0  0   0  0  0  0   0  0  0   
7 5 0 7     0  0  0  0   0  0  0  0   0  0 ...   0  0   0  0  0  0   0  0  0   
8 4 3 8     0  0  0  0   0  0  0  0   0  0 ...   0  0   0  0  0  0   0  0  0   
9 1 4 0     0  0  0  0   0  0  0  0   0  0 ...   0  0   0  0  0  0   0  0  0   

variables     
level         
days       4  
A B C D       
7 1 6 8    0  
4 0 5 6    0  
7 5 0 7    0  
8 4 3 8    0  
9 1 4 0    0  

[5 rows x 60 columns]
...