официальные документы

акое пивот?Как мне повернуть?Это стержень?Длинный формат для широкого формата?

Я видел много вопросов о сводных таблицах. Даже если они не знают, что спрашивают о сводных таблицах, они обычно так и делают. Практически невозможно написать канонический вопрос и ответ, который охватывает все аспекты поворота ....

... Но я собираюсь попробовать.

Проблема с существующими вопросами и ответами состоит в том, что часто вопрос фокусируется на нюансе, который ОП затрудняет обобщение, чтобы использовать ряд существующих хороших ответов. Однако ни один из ответов не пытается дать исчерпывающее объяснение (потому что это сложная задача)

Посмотрите несколько примеров из моегопоиск Гугл

Как развернуть датафрейм в Pandas?Хороший вопрос и ответ. Но ответ только отвечает на конкретный вопрос с небольшим объяснением.сводная таблица панд к фрейму данныхВ этом вопросе OP касается вывода разворота. А именно, как выглядят колонны. ОП хотел, чтобы это выглядело как R. Это не очень полезно для пользователей панд.Панды, поворачивающие фрейм данных, повторяющиеся строкиЕще один достойный вопрос, но ответ сосредоточен на одном методе, а именноpd.DataFrame.pivot

Поэтому, когда кто-то ищетpivot они получают спорадические результаты, которые, вероятно, не будут отвечать на их конкретный вопрос.

Настроить

Вы можете заметить, что я явно назвал свои столбцы и соответствующие значения столбцов в соответствии с тем, как я собираюсь поворачиваться в ответах ниже. Обратите внимание, чтобы вы узнали, куда идут имена столбцов, где можно получить результаты, которые вы ищете.

import numpy as np
import pandas as pd
from numpy.core.defchararray import add

np.random.seed([3,1415])
n = 20

cols = np.array(['key', 'row', 'item', 'col'])
arr1 = (np.random.randint(5, size=(n, 4)) // [2, 1, 2, 1]).astype(str)

df = pd.DataFrame(
    add(cols, arr1), columns=cols
).join(
    pd.DataFrame(np.random.rand(n, 2).round(2)).add_prefix('val')
)
print(df)

     key   row   item   col  val0  val1
0   key0  row3  item1  col3  0.81  0.04
1   key1  row2  item1  col2  0.44  0.07
2   key1  row0  item1  col0  0.77  0.01
3   key0  row4  item0  col2  0.15  0.59
4   key1  row0  item2  col1  0.81  0.64
5   key1  row2  item2  col4  0.13  0.88
6   key2  row4  item1  col3  0.88  0.39
7   key1  row4  item1  col1  0.10  0.07
8   key1  row0  item2  col4  0.65  0.02
9   key1  row2  item0  col2  0.35  0.61
10  key2  row0  item2  col1  0.40  0.85
11  key2  row4  item1  col2  0.64  0.25
12  key0  row2  item2  col3  0.50  0.44
13  key0  row4  item1  col4  0.24  0.46
14  key1  row3  item2  col3  0.28  0.11
15  key0  row3  item1  col1  0.31  0.23
16  key0  row0  item2  col3  0.86  0.01
17  key0  row4  item0  col3  0.64  0.21
18  key2  row2  item2  col0  0.13  0.45
19  key0  row2  item0  col4  0.37  0.70
Вопросов)

Почему я получаюValueError: Index contains duplicate entries, cannot reshape

Как я поворачиваюсьdf такой, чтоcol значения являются столбцами,row значения являются индексом и средним значениемval0 значения?

col   col0   col1   col2   col3  col4
row                                  
row0  0.77  0.605    NaN  0.860  0.65
row2  0.13    NaN  0.395  0.500  0.25
row3   NaN  0.310    NaN  0.545   NaN
row4   NaN  0.100  0.395  0.760  0.24

Как я поворачиваюсьdf такой, чтоcol значения являются столбцами,row значения являются индексом, средним значениемval0 значения, а пропущенные значения0?

col   col0   col1   col2   col3  col4
row                                  
row0  0.77  0.605  0.000  0.860  0.65
row2  0.13  0.000  0.395  0.500  0.25
row3  0.00  0.310  0.000  0.545  0.00
row4  0.00  0.100  0.395  0.760  0.24

Могу ли я получить что-то кромеmeanвроде как можетsum?

col   col0  col1  col2  col3  col4
row                               
row0  0.77  1.21  0.00  0.86  0.65
row2  0.13  0.00  0.79  0.50  0.50
row3  0.00  0.31  0.00  1.09  0.00
row4  0.00  0.10  0.79  1.52  0.24

Могу ли я сделать больше одной агрегации за раз?

       sum                          mean                           
col   col0  col1  col2  col3  col4  col0   col1   col2   col3  col4
row                                                                
row0  0.77  1.21  0.00  0.86  0.65  0.77  0.605  0.000  0.860  0.65
row2  0.13  0.00  0.79  0.50  0.50  0.13  0.000  0.395  0.500  0.25
row3  0.00  0.31  0.00  1.09  0.00  0.00  0.310  0.000  0.545  0.00
row4  0.00  0.10  0.79  1.52  0.24  0.00  0.100  0.395  0.760  0.24

Могу ли я объединить несколько столбцов значений?

      val0                             val1                          
col   col0   col1   col2   col3  col4  col0   col1  col2   col3  col4
row                                                                  
row0  0.77  0.605  0.000  0.860  0.65  0.01  0.745  0.00  0.010  0.02
row2  0.13  0.000  0.395  0.500  0.25  0.45  0.000  0.34  0.440  0.79
row3  0.00  0.310  0.000  0.545  0.00  0.00  0.230  0.00  0.075  0.00
row4  0.00  0.100  0.395  0.760  0.24  0.00  0.070  0.42  0.300  0.46

Можно разделить на несколько столбцов?

item item0             item1                         item2                   
col   col2  col3  col4  col0  col1  col2  col3  col4  col0   col1  col3  col4
row                                                                          
row0  0.00  0.00  0.00  0.77  0.00  0.00  0.00  0.00  0.00  0.605  0.86  0.65
row2  0.35  0.00  0.37  0.00  0.00  0.44  0.00  0.00  0.13  0.000  0.50  0.13
row3  0.00  0.00  0.00  0.00  0.31  0.00  0.81  0.00  0.00  0.000  0.28  0.00
row4  0.15  0.64  0.00  0.00  0.10  0.64  0.88  0.24  0.00  0.000  0.00  0.00

Или же

item      item0             item1                         item2                  
col        col2  col3  col4  col0  col1  col2  col3  col4  col0  col1  col3  col4
key  row                                                                         
key0 row0  0.00  0.00  0.00  0.00  0.00  0.00  0.00  0.00  0.00  0.00  0.86  0.00
     row2  0.00  0.00  0.37  0.00  0.00  0.00  0.00  0.00  0.00  0.00  0.50  0.00
     row3  0.00  0.00  0.00  0.00  0.31  0.00  0.81  0.00  0.00  0.00  0.00  0.00
     row4  0.15  0.64  0.00  0.00  0.00  0.00  0.00  0.24  0.00  0.00  0.00  0.00
key1 row0  0.00  0.00  0.00  0.77  0.00  0.00  0.00  0.00  0.00  0.81  0.00  0.65
     row2  0.35  0.00  0.00  0.00  0.00  0.44  0.00  0.00  0.00  0.00  0.00  0.13
     row3  0.00  0.00  0.00  0.00  0.00  0.00  0.00  0.00  0.00  0.00  0.28  0.00
     row4  0.00  0.00  0.00  0.00  0.10  0.00  0.00  0.00  0.00  0.00  0.00  0.00
key2 row0  0.00  0.00  0.00  0.00  0.00  0.00  0.00  0.00  0.00  0.40  0.00  0.00
     row2  0.00  0.00  0.00  0.00  0.00  0.00  0.00  0.00  0.13  0.00  0.00  0.00
     row4  0.00  0.00  0.00  0.00  0.00  0.64  0.88  0.00  0.00  0.00  0.00  0.00

Могу ли я объединить частоту, с которой столбец и строки встречаются вместе, то есть «кросс-табуляция»?

col   col0  col1  col2  col3  col4
row                               
row0     1     2     0     1     1
row2     1     0     2     1     2
row3     0     1     0     2     0
row4     0     1     2     2     1

Ответы на вопрос(1)

Решение Вопроса

Вопрос 1

Почему я получаюValueError: Index contains duplicate entries, cannot reshape

Это происходит потому, что панды пытаются переиндексироватьcolumns или жеindex объект с повторяющимися записями. Существуют различные методы, которые могут использовать для разворота. Некоторые из них не очень подходят, когда есть дубликаты клавиш, в которых его просят повернуть. Например. Рассмотреть возможностьpd.DataFrame.pivot, Я знаю, что есть повторяющиеся записи, которые разделяютrow а такжеcol ценности:

df.duplicated(['row', 'col']).any()

True

Итак, когда яpivot с помощью

df.pivot(index='row', columns='col', values='val0')

Я получаю ошибку, упомянутую выше. Фактически, я получаю ту же ошибку, когда пытаюсь выполнить ту же задачу с:

df.set_index(['row', 'col'])['val0'].unstack()

Вот список идиом, которые мы можем использовать для поворота

pd.DataFrame.groupby + pd.DataFrame.unstackХороший общий подход для выполнения практически любого типа разворотаВы указываете все столбцы, которые будут составлять поворотные уровни строк и уровни столбцов в одной группе. Вы следуете за этим, выбирая оставшиеся столбцы, которые вы хотите агрегировать, и функции, которые вы хотите выполнить агрегацию. Наконец-то выunstack уровни, которые вы хотите быть в индексе столбца.pd.DataFrame.pivot_tableПрославленная версияgroupby с более интуитивным API. Для многих это предпочтительный подход. И это намеченный подход со стороны разработчиков.Укажите уровень строки, уровни столбцов, значения для агрегирования и функции для выполнения агрегации.pd.DataFrame.set_index + pd.DataFrame.unstackУдобный и интуитивно понятный для некоторых (включая меня). Не удается обработать дублированные сгруппированные ключи.Похож наgroupby В парадигме мы указываем все столбцы, которые в конечном итоге будут уровнями строк или столбцов, и устанавливаем их в качестве индекса. Мы тогдаunstack уровни, которые мы хотим в столбцах. Если оставшиеся уровни индекса или уровни столбца не являются уникальными, этот метод завершится ошибкой.pd.DataFrame.pivotОчень похоже наset_index в том, что он разделяет ограничение дубликата ключа. API также очень ограничен. Он принимает только скалярные значения дляindex, columns, values.Похож наpivot_table Метод в том, что мы выбираем строки, столбцы и значения для поворота. Однако мы не можем агрегировать, и если строки или столбцы не являются уникальными, этот метод завершится ошибкой.pd.crosstabЭто специализированная версияpivot_table и в чистом виде это наиболее интуитивно понятный способ выполнения нескольких задач.pd.factorize + np.bincountЭто очень продвинутая техника, которая очень непонятна, но очень быстра. Его нельзя использовать при любых обстоятельствах, но когда его можно использовать, и вы можете его использовать, вы получите плоды производительности.pd.get_dummies + pd.DataFrame.dotЯ использую это для умного выполнения кросс-табуляции.Примеры

Что я собираюсь сделать для каждого последующего ответа и вопроса, чтобы ответить на него, используяpd.DataFrame.pivot_table, Затем я предоставлю альтернативы для выполнения той же задачи.

Вопрос 3

Как я поворачиваюсьdf такой, чтоcol значения являются столбцами,row значения являются индексом, средним значениемval0 значения, а пропущенные значения0?

pd.DataFrame.pivot_table

fill_value не установлено по умолчанию. Я склонен устанавливать это соответствующим образом. В этом случае я установил его0, Обратите внимание, что я пропустилвопрос 2 так же, как этот ответ безfill_value

aggfunc='mean' по умолчанию, и мне не нужно было его устанавливать. Я включил это, чтобы быть явным.

df.pivot_table(
    values='val0', index='row', columns='col',
    fill_value=0, aggfunc='mean')

col   col0   col1   col2   col3  col4
row                                  
row0  0.77  0.605  0.000  0.860  0.65
row2  0.13  0.000  0.395  0.500  0.25
row3  0.00  0.310  0.000  0.545  0.00
row4  0.00  0.100  0.395  0.760  0.24

pd.DataFrame.groupby

df.groupby(['row', 'col'])['val0'].mean().unstack(fill_value=0)

pd.crosstab

pd.crosstab(
    index=df['row'], columns=df['col'],
    values=df['val0'], aggfunc='mean').fillna(0)
Вопрос 4

Могу ли я получить что-то кромеmeanвроде как можетsum?

pd.DataFrame.pivot_table

df.pivot_table(
    values='val0', index='row', columns='col',
    fill_value=0, aggfunc='sum')

col   col0  col1  col2  col3  col4
row                               
row0  0.77  1.21  0.00  0.86  0.65
row2  0.13  0.00  0.79  0.50  0.50
row3  0.00  0.31  0.00  1.09  0.00
row4  0.00  0.10  0.79  1.52  0.24

pd.DataFrame.groupby

df.groupby(['row', 'col'])['val0'].sum().unstack(fill_value=0)

pd.crosstab

pd.crosstab(
    index=df['row'], columns=df['col'],
    values=df['val0'], aggfunc='sum').fillna(0)
Вопрос 5

Могу ли я сделать больше одной агрегации за раз?

Обратите внимание, что дляpivot_table а такжеcross_tab Мне нужно было пройти список вызовов. С другой стороны,groupby.agg способен принимать строки для ограниченного числа специальных функций.groupby.agg также взял бы те же самые вызовы, которые мы передали другим, но часто более эффективно использовать имена строковых функций, поскольку есть эффективность, которую нужно получить.

pd.DataFrame.pivot_table

df.pivot_table(
    values='val0', index='row', columns='col',
    fill_value=0, aggfunc=[np.size, np.mean])

     size                      mean                           
col  col0 col1 col2 col3 col4  col0   col1   col2   col3  col4
row                                                           
row0    1    2    0    1    1  0.77  0.605  0.000  0.860  0.65
row2    1    0    2    1    2  0.13  0.000  0.395  0.500  0.25
row3    0    1    0    2    0  0.00  0.310  0.000  0.545  0.00
row4    0    1    2    2    1  0.00  0.100  0.395  0.760  0.24

pd.DataFrame.groupby

df.groupby(['row', 'col'])['val0'].agg(['size', 'mean']).unstack(fill_value=0)

pd.crosstab

pd.crosstab(
    index=df['row'], columns=df['col'],
    values=df['val0'], aggfunc=[np.size, np.mean]).fillna(0, downcast='infer')
Вопрос 6

Могу ли я объединить несколько столбцов значений?

pd.DataFrame.pivot_table мы проходимvalues=['val0', 'val1'] но мы могли бы оставить это полностью

df.pivot_table(
    values=['val0', 'val1'], index='row', columns='col',
    fill_value=0, aggfunc='mean')

      val0                             val1                          
col   col0   col1   col2   col3  col4  col0   col1  col2   col3  col4
row                                                                  
row0  0.77  0.605  0.000  0.860  0.65  0.01  0.745  0.00  0.010  0.02
row2  0.13  0.000  0.395  0.500  0.25  0.45  0.000  0.34  0.440  0.79
row3  0.00  0.310  0.000  0.545  0.00  0.00  0.230  0.00  0.075  0.00
row4  0.00  0.100  0.395  0.760  0.24  0.00  0.070  0.42  0.300  0.46

pd.DataFrame.groupby

df.groupby(['row', 'col'])['val0', 'val1'].mean().unstack(fill_value=0)
Вопрос 7

Можно разделить на несколько столбцов?

pd.DataFrame.pivot_table

df.pivot_table(
    values='val0', index='row', columns=['item', 'col'],
    fill_value=0, aggfunc='mean')

item item0             item1                         item2                   
col   col2  col3  col4  col0  col1  col2  col3  col4  col0   col1  col3  col4
row                                                                          
row0  0.00  0.00  0.00  0.77  0.00  0.00  0.00  0.00  0.00  0.605  0.86  0.65
row2  0.35  0.00  0.37  0.00  0.00  0.44  0.00  0.00  0.13  0.000  0.50  0.13
row3  0.00  0.00  0.00  0.00  0.31  0.00  0.81  0.00  0.00  0.000  0.28  0.00
row4  0.15  0.64  0.00  0.00  0.10  0.64  0.88  0.24  0.00  0.000  0.00  0.00

pd.DataFrame.groupby

df.groupby(
    ['row', 'item', 'col']
)['val0'].mean().unstack(['item', 'col']).fillna(0).sort_index(1)
Вопрос 8

Можно разделить на несколько столбцов?

pd.DataFrame.pivot_table

df.pivot_table(
    values='val0', index=['key', 'row'], columns=['item', 'col'],
    fill_value=0, aggfunc='mean')

item      item0             item1                         item2                  
col        col2  col3  col4  col0  col1  col2  col3  col4  col0  col1  col3  col4
key  row                                                                         
key0 row0  0.00  0.00  0.00  0.00  0.00  0.00  0.00  0.00  0.00  0.00  0.86  0.00
     row2  0.00  0.00  0.37  0.00  0.00  0.00  0.00  0.00  0.00  0.00  0.50  0.00
     row3  0.00  0.00  0.00  0.00  0.31  0.00  0.81  0.00  0.00  0.00  0.00  0.00
     row4  0.15  0.64  0.00  0.00  0.00  0.00  0.00  0.24  0.00  0.00  0.00  0.00
key1 row0  0.00  0.00  0.00  0.77  0.00  0.00  0.00  0.00  0.00  0.81  0.00  0.65
     row2  0.35  0.00  0.00  0.00  0.00  0.44  0.00  0.00  0.00  0.00  0.00  0.13
     row3  0.00  0.00  0.00  0.00  0.00  0.00  0.00  0.00  0.00  0.00  0.28  0.00
     row4  0.00  0.00  0.00  0.00  0.10  0.00  0.00  0.00  0.00  0.00  0.00  0.00
key2 row0  0.00  0.00  0.00  0.00  0.00  0.00  0.00  0.00  0.00  0.40  0.00  0.00
     row2  0.00  0.00  0.00  0.00  0.00  0.00  0.00  0.00  0.13  0.00  0.00  0.00
     row4  0.00  0.00  0.00  0.00  0.00  0.64  0.88  0.00  0.00  0.00  0.00  0.00

pd.DataFrame.groupby

df.groupby(
    ['key', 'row', 'item', 'col']
)['val0'].mean().unstack(['item', 'col']).fillna(0).sort_index(1)

pd.DataFrame.set_index потому что набор ключей уникален как для строк, так и для столбцов

df.set_index(
    ['key', 'row', 'item', 'col']
)['val0'].unstack(['item', 'col']).fillna(0).sort_index(1)
Вопрос 9

Могу ли я объединить частоту, с которой столбец и строки встречаются вместе, то есть «кросс-табуляция»?

pd.DataFrame.pivot_table

df.pivot_table(index='row', columns='col', fill_value=0, aggfunc='size')

    col   col0  col1  col2  col3  col4
row                               
row0     1     2     0     1     1
row2     1     0     2     1     2
row3     0     1     0     2     0
row4     0     1     2     2     1

pd.DataFrame.groupby

df.groupby(['row', 'col'])['val0'].size().unstack(fill_value=0)

pd.cross_tab

pd.crosstab(df['row'], df['col'])

pd.factorize + np.bincount

# get integer factorization `i` and unique values `r`
# for column `'row'`
i, r = pd.factorize(df['row'].values)
# get integer factorization `j` and unique values `c`
# for column `'col'`
j, c = pd.factorize(df['col'].values)
# `n` will be the number of rows
# `m` will be the number of columns
n, m = r.size, c.size
# `i * m + j` is a clever way of counting the 
# factorization bins assuming a flat array of length
# `n * m`.  Which is why we subsequently reshape as `(n, m)`
b = np.bincount(i * m + j, minlength=n * m).reshape(n, m)
# BTW, whenever I read this, I think 'Bean, Rice, and Cheese'
pd.DataFrame(b, r, c)

      col3  col2  col0  col1  col4
row3     2     0     0     1     0
row2     1     2     1     0     2
row0     1     0     1     2     1
row4     2     2     0     1     1

pd.get_dummies

pd.get_dummies(df['row']).T.dot(pd.get_dummies(df['col']))

      col0  col1  col2  col3  col4
row0     1     2     0     1     1
row2     1     0     2     1     2
row3     0     1     0     2     0
row4     0     1     2     2     1
 MaxU15 дек. 2017 г., 11:31
Не могли бы вы рассмотреть вопрос о продленииофициальные документы?

Ваш ответ на вопрос