У меня есть список. Я хочу, чтобы set_index dataframe в форме декартового произведения значений списка с dataframe, т.е.

li = ['A','B']
df = pd.DataFrame([[0,0,0],[1,1,1],[2,2,2]])

Я хочу, чтобы итоговый кадр данных был похож

   0  1  2
A  0  0  0
A  1  1  1
A  2  2  2
B  0  0  0
B  1  1  1
B  2  2  2

Как я могу это сделать?

2
Bharath 28 Авг 2017 в 18:54

3 ответа

Лучший ответ

Вариант 1
pd.concat с аргументом keys

pd.concat([df] * len(li), keys=li) 

     0  1  2
A 0  0  0  0
  1  1  1  1
  2  2  2  2
B 0  0  0  0
  1  1  1  1
  2  2  2  2

Чтобы точно воспроизвести ваш вывод:

pd.concat([df] * len(li), keys=li).reset_index(1, drop=True)

   0  1  2
A  0  0  0
A  1  1  1
A  2  2  2
B  0  0  0
B  1  1  1
B  2  2  2

Вариант 2
np.tile и np.repeat

pd.DataFrame(np.tile(df, [len(li), 1]), np.repeat(li, len(df)), df.columns)

   0  1  2
A  0  0  0
A  1  1  1
A  2  2  2
B  0  0  0
B  1  1  1
B  2  2  2
3
piRSquared 28 Авг 2017 в 16:07

Используйте MultiIndex.from_product с < a href = "http://pandas.pydata.org/pandas-docs/stable/generated/pandas.DataFrame.reindex.html" rel = "nofollow noreferrer"> reindex :

mux = pd.MultiIndex.from_product([li, df.index])
df = df.reindex(mux, level=1).reset_index(level=1, drop=True)
print (df)
   0  1  2
A  0  0  0
A  1  1  1
A  2  2  2
B  0  0  0
B  1  1  1
B  2  2  2
2
jezrael 28 Авг 2017 в 15:57

Или вы можете использовать.

li = [['A','B']]
df['New']=li*len(df)
df.set_index([0,1,2])['New'].apply(pd.Series).stack().to_frame().rename(columns={0:'keys'})\
     .reset_index().drop('level_3',1).sort_values('keys')

Out[698]: 
   0  1  2 keys
0  0  0  0    A
2  1  1  1    A
4  2  2  2    A
1  0  0  0    B
3  1  1  1    B
5  2  2  2    B
0
YOBEN_S 28 Авг 2017 в 16:16