Изменить форму от длинного до широкого, используя имена столбцов - PullRequest
7 голосов
/ 08 июля 2019

Привет, у меня проблемы с изменением моего df.

У меня есть:

Netflix     TV      DVD 
   0.1      0.2     0.3
   0.12     0.5     0.15
   0.4      0.6     0.8
            0.5     0.41
            0.41
            0.2 

И я хочу, чтобы мой df выглядел так:

Netflix  [0.1, 0.12, 0.4]
TV       [0.2, 0.5, 0.6, 0.5, 0.41, 0.2] 
DVD      [0.3, 0.15, 0.8, 0.41]

Не уверен, как stack () или pivot () будет работать на df такого типа. Любая помощь приветствуется.

Ответы [ 5 ]

9 голосов
/ 08 июля 2019

stack

Stacking сбрасывает нулевые значения при изменении формы массива

df.stack().groupby(level=1).agg(list)

DVD                 [0.3, 0.15, 0.8, 0.41]
Netflix                   [0.1, 0.12, 0.4]
TV         [0.2, 0.5, 0.6, 0.5, 0.41, 0.2]
dtype: object
7 голосов
/ 08 июля 2019

Удалите пропущенные значения на Series.dropna и преобразуйте в Серии в словаре:

s = pd.Series({x: df[x].dropna().tolist() for x in df.columns})
print (s)
Netflix                   [0.1, 0.12, 0.4]
TV         [0.2, 0.5, 0.6, 0.5, 0.41, 0.2]
DVD                 [0.3, 0.15, 0.8, 0.41]
dtype: object

... или в DataFrame.apply:

s = df.apply(lambda x: x.dropna().tolist())
print (s)

Netflix                   [0.1, 0.12, 0.4]
TV         [0.2, 0.5, 0.6, 0.5, 0.41, 0.2]
DVD                 [0.3, 0.15, 0.8, 0.41]
dtype: object

Последнее, если нужно 2 столбца DataFrame:

df1 = s.rename_axis('a').reset_index(name='b')
print (df1)
         a                                b
0  Netflix                 [0.1, 0.12, 0.4]
1       TV  [0.2, 0.5, 0.6, 0.5, 0.41, 0.2]
2      DVD           [0.3, 0.15, 0.8, 0.41]
4 голосов
/ 08 июля 2019

Я думаю, это то, что вы ищете:

> df.T.apply(lambda x: x.dropna().tolist(), axis=1)

Netflix    [0.1, 0.12, 0.4, 0.5, 0.41, 0.2]
TV                    [0.2, 0.5, 0.6, 0.41]
DVD                        [0.3, 0.15, 0.8]
dtype: object
2 голосов
/ 08 июля 2019

Использование groupby с columns

df.groupby(level=0,axis=1).apply(lambda x : x.dropna().iloc[:,0].tolist())
Out[20]: 
DVD                 [0.3, 0.15, 0.8, 0.41]
Netflix                   [0.1, 0.12, 0.4]
TV         [0.2, 0.5, 0.6, 0.5, 0.41, 0.2]
dtype: object
1 голос
/ 08 июля 2019

Если пропущенные значения в каждом столбце являются NaN, вы можете использовать следующее:

df1 = pd.DataFrame({
    "Netflix":  [0.1, 0.12, 0.4, None, None, None],
    "TV":       [0.2, 0.5, 0.6, 0.5, 0.41, 0.2],
    "DVD":      [0.3, 0.15, 0.8, 0.41, None, None]
}
)
print(df1)

df2 = pd.DataFrame(df1.columns, columns=["Type"])
df2["List_for_Type"] = [
    list(df1[f].dropna())
    for f in df1.columns
]
print(df2)

Соответствующий вывод:

  Netflix    TV   DVD
0     0.10  0.20  0.30
1     0.12  0.50  0.15
2     0.40  0.60  0.80
3      NaN  0.50  0.41
4      NaN  0.41   NaN
5      NaN  0.20   NaN

      Type                    List_for_Type
0  Netflix                 [0.1, 0.12, 0.4]
1       TV  [0.2, 0.5, 0.6, 0.5, 0.41, 0.2]
2      DVD           [0.3, 0.15, 0.8, 0.41]

Надеюсь, это поможет.

...