Как объединить многомерный массив данных и серии разной длины? - PullRequest
1 голос
/ 14 марта 2019

Есть ли способ объединить многомерный фрейм данных с сериями разной длины?Есть так много способов объединить DF.Я читал о присоединении, объединении, добавлении и объединении.Я не знаю, какой из них использовать.Кроме того, у всех есть много дополнительных параметров, что делает его еще более сложным для понимания.Может ли кто-нибудь уточнить документацию (https://pandas.pydata.org/pandas-docs/stable/user_guide/merging.html),, в частности, о том, как объединить фрейм данных и серии различной длины?

Например, я хотел бы объединить следующий многомерный фрейм данных,

d = {'Name': ['Kitty', 'Harry', 'Bear', 'Sam', 'Max', 'Hunter', 'Fluffy'], 'Favloc': ['couch', 'windowsill', 'bed', 'basket', 'floor', 'carpet', 'haybale'], 'Pet': ['Cat', 'Cat', 'Cat', 'Dog', 'Dog', 'Dog', 'Hamster']}
df = pd.DataFrame(data=d)
df = df.set_index(['Pet', 'Name'])

print (df)
                 Favloc
Pet     Name           
Cat     Kitty     couch
        Harry   windows
        Bear        bed
        Sam      basket
Dog     Max       floor
        Hunter   carper

со следующими Сериями, s1:

s1 = pd.Series([3,3,1], index=['Cat','Dog','Hamster'])

Я бы хотел, чтобы результат был:

                      Favloc
Pet     cnts Name           
Cat     3    Kitty     couch
             Harry   windows
             Bear        bed
             Sam      basket
Dog     3    Max       floor
             Hunter   carper
Hamster 1    Fluffy  Haybale

Я уже пробовал

result = df.join(s1)

Но это выдает ошибку:

Cannot join with no level specified and no overlapping names

Я понимаю, что не указал уровень, но не знаю, как его указать. Должен ли я сказать уровень 1, потому что я хотел бы, чтобы cntsбыть на уровне 1 уровня? (с Favloc, являющимся уровнем 0? Кроме того, я не понимаю 'без перекрывающихся имен', потому что кошка, собака и хомяк перекрываются, верно?

Я также пытался

result = pd.concat([df, s1])

Это привело к созданию кадра данных с NAN в каждом столбце, где я хотел бы видеть cnts.

Затем я попытался:

result = pd.merge(df, s1)

И я получил: не могуобъединить DataFrame с экземпляром типа

Я попробовал все из них со всевозможными аргументами, но я неНе думаю, что это помогает показать все, что я пробовал?Я думаю, что много пытался, потому что я не очень понимаю, как работает объединение многомерного кадра данных и серии различной длины.

Я видел похожие вопросы, но все с фреймами данных только с одним уровнем, например: Как объединить ряд и фрейм данных Итак, как объединить многомерный кадр данных и ряды различной длины?

1 Ответ

2 голосов
/ 14 марта 2019

Вы можете использовать DataFrame.join с rename и параметром on, затем DataFrame.set_index с DataFrame.reorder_levels:

result = (df.join(s1.rename('cnts'), on='Pet')
           .set_index('cnts', append=True)
           .reorder_levels([0,2,1]))
print (result)
                      Favloc
Pet     cnts Name           
Cat     3    Kitty     couch
             Harry   windows
             Bear        bed
             Sam      basket
Dog     3    Max       floor
             Hunter   carper
Hamster 1    Fluffy  Haybale

Или используйте Index.map:

idx = df.index.get_level_values('Pet').map(s1.rename('cnts').get)
result = df.set_index(idx, append=True).reorder_levels([0,2,1])
print (result)
                      Favloc
Pet     cnts Name           
Cat     3    Kitty     couch
             Harry   windows
             Bear        bed
             Sam      basket
Dog     3    Max       floor
             Hunter   carper
Hamster 1    Fluffy  Haybale
...