Какой самый простой способ транспонировать / инвертировать пандас данных? - PullRequest
0 голосов
/ 28 августа 2018

У меня есть следующий кадр данных панд:

Person     Item1      Item2     Item3     Item4
Adam       Apple      Eggs      Cookie
Alex       Chocolate  Orange    Eggs      Potato
Gina       Eggs       Apple     Orange    Milk

Я хочу преобразовать это в это:

Item      Count     Person1     Person2     Person3
Apple     2         Adam        Gina
Eggs      3         Adam        Alex        Gina
Cookie    1         Adam
Chocolate 1         Alex
Orange    2         Alex        Gina
Potato    1         Alex
Milk      1         Gina

Я тщательно искал свой запрос перед публикацией, но я не нашел ни одного совпадения (возможно, есть лучший способ перефразировать мой вопрос). Мне жаль, если это дубликат, но если это так, пожалуйста, направьте меня туда, где ранее был дан ответ на этот вопрос.

Ответы [ 2 ]

0 голосов
/ 28 августа 2018

Используйте melt для изменения формы:

df = df.melt('Person', value_name='Item')
print (df)
   Person variable       Item
0    Adam    Item1      Apple
1    Alex    Item1  Chocolate
2    Gina    Item1       Eggs
3    Adam    Item2       Eggs
4    Alex    Item2     Orange
5    Gina    Item2      Apple
6    Adam    Item3     Cookie
7    Alex    Item3       Eggs
8    Gina    Item3     Orange
9    Adam    Item4        NaN
10   Alex    Item4     Potato
11   Gina    Item4       Milk

Затем объедините пользовательскую функцию для list s с GroupBy.size, а затем создайте новый DataFrame с помощью конструктора и join для подсчета столбца:

f = lambda x: x.tolist()
f.__name__ = 'Person'
df1 = df.groupby('Item', sort=False)['Person'].agg([f, 'size'])

df2 = pd.DataFrame(df1.pop('Person').values.tolist(), index=df1.index).add_prefix('Person')
df3 = df1.join(df2).reset_index()
print (df3)
        Item  size Person0 Person1 Person2
0      Apple     2    Adam    Gina    None
1  Chocolate     1    Alex    None    None
2       Eggs     3    Gina    Adam    Alex
3     Orange     2    Alex    Gina    None
4     Cookie     1    Adam    None    None
5     Potato     1    Alex    None    None
6       Milk     1    Gina    None    None
0 голосов
/ 28 августа 2018

Это не совсем то, что вы ищете, но я не уверен, что «транспонирование» существует как простая функция. (Кстати, transpose, следуя линейной алгебре, обычно означает поворот кадра данных на 90 °).

# get items
items = []
for c in df.columns[1:]:
    items.extend(df[c].values)
items = list(set(items))
items.remove(None)

people = df.Person.values
counts = {}
for p in people:
    counts[p] = [1 if item in df[df['Person'] == p].values else 0 for item in items]

new = pd.DataFrame(counts, index=items)
new['Count'] = new.sum(axis=1)

Выход:

|           | Adam | Alex | Gina | Count |
|-----------|------|------|------|-------|
| Cookie    | 1    | 0    | 0    | 1     |
| Chocolate | 0    | 1    | 0    | 1     |
| Potato    | 0    | 1    | 0    | 1     |
| Eggs      | 1    | 1    | 1    | 3     |
| Milk      | 0    | 0    | 1    | 1     |
| Orange    | 0    | 1    | 1    | 2     |
| Apple     | 1    | 0    | 1    | 2     |

РЕДАКТИРОВАТЬ: как обычно, у Jezrael есть правильный ответ, но я настроил это, чтобы получить желаемый результат. Это может быть немного проще для начинающего.

В качестве примера приведем 'df':

item_counts = {}
for item in items:
    counts = {}
    count = 0
    for p in people:
        if item in df[df['Person'] == p].values:
            count += 1
            counts['Person' + str(count)] = p
    counts['count'] = count
    item_counts[item] = counts

new = pd.DataFrame.from_dict(item_counts, orient='index')
new = new[['count', 'Person1', 'Person2', 'Person3']] # rearrange columns, optional

Выход:

|           | count | Person1 | Person2 | Person3 |
|-----------|-------|---------|---------|---------|
| Apple     | 2     | Adam    | Gina    | NaN     |
| Chocolate | 1     | Alex    | NaN     | NaN     |
| Cookie    | 1     | Adam    | NaN     | NaN     |
| Eggs      | 3     | Adam    | Alex    | Gina    |
| Milk      | 1     | Gina    | NaN     | NaN     |
| Orange    | 2     | Alex    | Gina    | NaN     |
| Potato    | 1     | Alex    | NaN     | NaN     |
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...