Pandas кадр данных из словаря
У меня есть словарь python для рейтинга пользовательских элементов, который выглядит примерно так:
sample={'user1': {'item1': 2.5, 'item2': 3.5, 'item3': 3.0, 'item4': 3.5, 'item5': 2.5, 'item6': 3.0},
'user2': {'item1': 2.5, 'item2': 3.0, 'item3': 3.5, 'item4': 4.0},
'user3': {'item2':4.5,'item5':1.0,'item6':4.0}}
Я хотел преобразовать его в кадр данных pandas, который был бы структурирован как
col1 col2 col3
0 user1 item1 2.5
1 user1 item2 3.5
2 user1 item3 3.0
3 user1 item4 3.5
4 user1 item5 2.5
5 user1 item6 3.0
6 user2 item1 2.5
7 user2 item2 3.0
8 user2 item3 3.5
9 user2 item4 4.0
10 user3 item2 4.5
11 user3 item5 1.0
12 user3 item6 4.0
Любые идеи будут высоко оценены:)
Ответы
Ответ 1
Попробуйте выполнить следующий код:
import pandas
sample={'user1': {'item1': 2.5, 'item2': 3.5, 'item3': 3.0, 'item4': 3.5, 'item5': 2.5, 'item6': 3.0},
'user2': {'item1': 2.5, 'item2': 3.0, 'item3': 3.5, 'item4': 4.0},
'user3': {'item2':4.5,'item5':1.0,'item6':4.0}}
df = pandas.DataFrame([
[col1,col2,col3] for col1, d in sample.items() for col2, col3 in d.items()
])
Ответ 2
Я думаю, что операция, которую вы выполняете, - чтобы раскрыть таблицу - называется "таянием". В этом случае сложную часть можно выполнить с помощью pd.melt
, а все остальное - в основном переименование и переупорядочение:
df = pd.DataFrame(sample).reset_index().rename(columns={"index": "item"})
df = pd.melt(df, "item", var_name="user").dropna()
df = df[["user", "item", "value"]].reset_index(drop=True)
Просто вызов DataFrame
создает что-то, у которого есть информация, которую мы хотим, но имеет неправильную форму:
>>> df = pd.DataFrame(sample)
>>> df
user1 user2 user3
item1 2.5 2.5 NaN
item2 3.5 3.0 4.5
item3 3.0 3.5 NaN
item4 3.5 4.0 NaN
item5 2.5 NaN 1.0
item6 3.0 NaN 4.0
Итак, позвольте продвинуть индекс в настоящий столбец и улучшите имя:
>>> df = pd.DataFrame(sample).reset_index().rename(columns={"index": "item"})
>>> df
item user1 user2 user3
0 item1 2.5 2.5 NaN
1 item2 3.5 3.0 4.5
2 item3 3.0 3.5 NaN
3 item4 3.5 4.0 NaN
4 item5 2.5 NaN 1.0
5 item6 3.0 NaN 4.0
Затем мы можем вызвать pd.melt
, чтобы повернуть столбцы. Если мы не укажем имя переменной, которое мы хотим, "пользователь", это даст ему скучное имя "переменная" (точно так же, как оно дает самим данным скучное имя "значение" ).
>>> df = pd.melt(df, "item", var_name="user").dropna()
>>> df
item user value
0 item1 user1 2.5
1 item2 user1 3.5
2 item3 user1 3.0
3 item4 user1 3.5
4 item5 user1 2.5
5 item6 user1 3.0
6 item1 user2 2.5
7 item2 user2 3.0
8 item3 user2 3.5
9 item4 user2 4.0
13 item2 user3 4.5
16 item5 user3 1.0
17 item6 user3 4.0
Наконец, мы можем изменить порядок и изменить нумерацию индексов:
>>> df = df[["user", "item", "value"]].reset_index(drop=True)
>>> df
user item value
0 user1 item1 2.5
1 user1 item2 3.5
2 user1 item3 3.0
3 user1 item4 3.5
4 user1 item5 2.5
5 user1 item6 3.0
6 user2 item1 2.5
7 user2 item2 3.0
8 user2 item3 3.5
9 user2 item4 4.0
10 user3 item2 4.5
11 user3 item5 1.0
12 user3 item6 4.0
melt
очень полезен, как только вы привыкнете к нему. Обычно, как здесь, вы выполняете переименование/переупорядочение до и после.
Ответ 3
Я предоставляю другую возможность здесь, используя pd.stack
:
df = pd.DataFrame(sample)
df = df.T.stack().reset_index()
Подробные объяснения
In [24]: df = pd.DataFrame(sample)
In [25]: df
Out[25]:
user1 user2 user3
item1 2.5 2.5 NaN
item2 3.5 3.0 4.5
item3 3.0 3.5 NaN
item4 3.5 4.0 NaN
item5 2.5 NaN 1.0
item6 3.0 NaN 4.0
Применение stack
будет поворачивать ось столбца на подуровне оси строки, уже проиндексированной item
. Как вы хотите user
сначала, сделайте операцию над транспонированным DataFrame с помощью .T
:
In [34]: df = df.T.stack()
In [35]: df
Out[35]:
user1 item1 2.5
item2 3.5
item3 3.0
item4 3.5
item5 2.5
item6 3.0
user2 item1 2.5
item2 3.0
item3 3.5
item4 4.0
user3 item2 4.5
item5 1.0
item6 4.0
dtype: float64
Вы ожидаете базовые столбцы, а не индекс, поэтому просто reset индекс:
In [36]: df = df.reset_index()
In [37]: df
Out[37]:
level_0 level_1 0
0 user1 item1 2.5
1 user1 item2 3.5
2 user1 item3 3.0
3 user1 item4 3.5
4 user1 item5 2.5
5 user1 item6 3.0
6 user2 item1 2.5
7 user2 item2 3.0
8 user2 item3 3.5
9 user2 item4 4.0
10 user3 item2 4.5
11 user3 item5 1.0
12 user3 item6 4.0
Ответ 4
Это очень похоже на решение melt
, предоставляемое DSM:
df = DataFrame(sample)
df = df.unstack().dropna().reset_index()
df = df.rename(columns={'level_0':'col1', 'level_1':'col2', 0:'col3'})
Ответ 5
Вы могли бы попробовать сделать это, как это возможно.
temp=[]
for item in sample:
temp.append(pandas.DataFrame(item))
self.results = pandas.concat(temp)