Pandas Dataframe: сдвигать / объединять несколько строк с одинаковыми значениями столбцов в одну строку - PullRequest
0 голосов
/ 30 ноября 2018

Извините за возможную путаницу с названием.Я опишу свой вопрос лучше с помощью следующего кода и рисунков.

Теперь у меня есть фрейм данных с несколькими столбцами.Первые два столбца, по которым они отсортированы, «Маршрут» и «Идентификатор» (Извините за форматирование, все строки здесь имеют значение «Маршрут», равное «100» и «Идентификатор» от 1 до 3.

df1.head(9)
  Route ID  Year    Vol Truck_Vol   Truck_%
0   100 1   2017.0  7016    635.0   9.1
1   100 1   2014.0  6835    NaN NaN
2   100 1   2011.0  5959    352.0   5.9
3   100 2   2018.0  15828   NaN NaN
4   100 2   2015.0  13114   2964.0  22.6
5   100 2   2009.0  11844   1280.0  10.8
6   100 3   2016.0  15434   NaN NaN
7   100 3   2013.0  18699   2015.0  10.8
8   100 3   2010.0  15903   NaN NaN

Я хочу получить

 Route  ID  Year    Vol1    Truck_Vol1  Truck_%1    Year2   Vol2    Truck_Vol2  Truck_%2    Year3   Vol3    Truck_Vol3  Truck_%3
0   100 1   2017    7016    635.0   9.1 2014    6835    NaN NaN 2011    5959    352.0   5.9
1   100 2   2018    15828   NaN NaN 2015    13114   2964.0  22.6    2009    11844   1280.0  10.8
2   100 3   2016    15434   NaN NaN 2013    18699   2015.0  10.8    2010    15903   NaN NaN

Опять же, извините за грязное форматирование. Позвольте мне попробовать упрощенную версию.

Ввод:

  Route ID  Year    Vol T_%
0   100 1   2017    100 1.0
1   100 1   2014    200 NaN
2   100 1   2011    300 2.0
3   100 2   2018    400 NaN
4   100 2   2015    500 3.0
5   100 2   2009    600 4.0

Желаемый результат:

Route   ID  Year    Vol T_% Year.1  Vol.1   T_%.1   Year.2  Vol.2   T_%.2
0   100 1   2017    100 1.0 2014    200     NaN     2011    300      2
1   100 2   2018    400 NaN 2015    500     3.0     2009    600      4

Так что просто переместите ячейки, показанные на рисунке

Input

Output

Я озадачен здесь. Имена вновь сгенерированных столбцов не имеют значения.

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

Спасибо за ваше время.

Ответы [ 2 ]

0 голосов
/ 30 ноября 2018

с groupby + cumcount + set_index + unstack

df1 = df.assign(cid = df.groupby(['Route', 'ID']).cumcount()).set_index(['Route', 'ID', 'cid']).unstack(-1).sort_index(1,1)
df1.columns = [f'{x}{y}' for x,y in df1.columns]
df1 = df1.reset_index()

Выход df1:

   Route  ID  T_%0  Vol0  Year0  T_%1  Vol1  Year1  T_%2  Vol2  Year2
0    100   1   1.0   100   2017   NaN   200   2014   2.0   300   2011
1    100   2   NaN   400   2018   3.0   500   2015   4.0   600   2009
0 голосов
/ 30 ноября 2018

melt + pivot_table

v = df.melt(id_vars=['Route', 'ID'])
v['variable'] += v.groupby(['Route', 'ID', 'variable']).cumcount().astype(str)

res = v.pivot_table(index=['Route', 'ID'], columns='variable', values='value')

variable  T_% 0  T_% 1  T_% 2  Vol 0  Vol 1  Vol 2  Year 0  Year 1  Year 2
Route ID
100   1     1.0    NaN    2.0  100.0  200.0  300.0  2017.0  2014.0  2011.0
      2     NaN    3.0    4.0  400.0  500.0  600.0  2018.0  2015.0  2009.0

Если вы хотите отсортировать их:

c = res.columns.str.extract(r'(\d+)')[0].values.astype(int)
res.iloc[:,np.argsort(c)]

variable  T_%0   Vol0   Year0  T_%1   Vol1   Year1  T_%2   Vol2   Year2
Route ID
100   1    1.0  100.0  2017.0   NaN  200.0  2014.0   2.0  300.0  2011.0
      2    NaN  400.0  2018.0   3.0  500.0  2015.0   4.0  600.0  2009.0

Вы спросили о том, почему я использовал cumcount.Чтобы объяснить, вот как выглядит v сверху:

    Route  ID variable   value
0     100   1     Year  2017.0
1     100   1     Year  2014.0
2     100   1     Year  2011.0
3     100   2     Year  2018.0
4     100   2     Year  2015.0
5     100   2     Year  2009.0
6     100   1      Vol   100.0
7     100   1      Vol   200.0
8     100   1      Vol   300.0
9     100   2      Vol   400.0
10    100   2      Vol   500.0
11    100   2      Vol   600.0
12    100   1      T_%     1.0
13    100   1      T_%     NaN
14    100   1      T_%     2.0
15    100   2      T_%     NaN
16    100   2      T_%     3.0
17    100   2      T_%     4.0

Если бы я использовал pivot_table в этом DataFrame, вы бы получили что-то вроде этого:

variable  T_%    Vol    Year
Route ID
100   1   1.5  200.0  2014.0
      2   3.5  500.0  2014.0

Очевидно, вы теряете данные здесь.cumcount - это решение, поскольку оно превращает серию variable в следующее:

    Route  ID variable   value
0     100   1    Year0  2017.0
1     100   1    Year1  2014.0
2     100   1    Year2  2011.0
3     100   2    Year0  2018.0
4     100   2    Year1  2015.0
5     100   2    Year2  2009.0
6     100   1     Vol0   100.0
7     100   1     Vol1   200.0
8     100   1     Vol2   300.0
9     100   2     Vol0   400.0
10    100   2     Vol1   500.0
11    100   2     Vol2   600.0
12    100   1     T_%0     1.0
13    100   1     T_%1     NaN
14    100   1     T_%2     2.0
15    100   2     T_%0     NaN
16    100   2     T_%1     3.0
17    100   2     T_%2     4.0

, где имеется количество повторяющихся элементов на уникальные Route и ID.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...