Df.apply(sorted, axis=1) удаляет имена столбцов?

Работаем через Pandas Cookbook. Подсчет общего количества рейсов между городами.

import pandas as pd
import numpy as np
# import matplotlib.pyplot as plt

print('NumPy: {}'.format(np.__version__))
print('Pandas: {}'.format(pd.__version__))
print('-----')

desired_width = 320
pd.set_option('display.width', desired_width)
pd.options.display.max_rows = 50
pd.options.display.max_columns = 14
# pd.options.display.float_format = '{:,.2f}'.format

file = "e:\\packt\\data_analysis_and_exploration_with_pandas\\section07\\data\\flights.csv"
flights = pd.read_csv(file)
print(flights.head(10))
print()

# This returns the total number of rows for each group.
flights_ct = flights.groupby(['ORG_AIR', 'DEST_AIR']).size()
print(flights_ct.head(10))
print()

# Get the number of flights between Atlanta and Houston in both directions.
print(flights_ct.loc[[('ATL', 'IAH'), ('IAH', 'ATL')]])
print()

# Sort the origin and destination cities:
# flights_sort = flights.sort_values(by=['ORG_AIR', 'DEST_AIR'], axis=1)
flights_sort = flights[['ORG_AIR', 'DEST_AIR']].apply(sorted, axis=1)
print(flights_sort.head(10))
print()

# Passing just the first row.
print(sorted(flights.loc[0, ['ORG_AIR', 'DEST_AIR']]))
print()

# Once each row is independently sorted, the column name are no longer correct.
# We will rename them to something generic, then again find the total number of flights between all cities.
rename_dict = {'ORG_AIR': 'AIR1', 'DEST_AIR': 'AIR2'}
flights_sort = flights_sort.rename(columns=rename_dict)
flights_ct2 = flights_sort.groupby(['AIR1', 'AIR2']).size()
print(flights_ct2.head(10))
print()

Когда я добираюсь до этой строки кода, мой вывод отличается от авторов:

```flights_sort = flights[['ORG_AIR', 'DEST_AIR']].apply(sorted, axis=1)```

Мой вывод не содержит имен столбцов. В результате, когда я доберусь до:

```flights_ct2 = flights_sort.groupby(['AIR1', 'AIR2']).size()```

он выдает KeyError. Это имеет смысл, так как я пытаюсь переименовать столбцы, когда имена столбцов не существуют.

Мой вопрос: почему имена столбцов исчезли? Все остальные выходные данные точно соответствуют выводам авторов:

Connected to pydev debugger (build 191.7141.48)
NumPy: 1.16.3
Pandas: 0.24.2
-----
   MONTH  DAY  WEEKDAY AIRLINE ORG_AIR DEST_AIR  SCHED_DEP  DEP_DELAY  AIR_TIME  DIST  SCHED_ARR  ARR_DELAY  DIVERTED  CANCELLED
0      1    1        4      WN     LAX      SLC       1625       58.0      94.0   590       1905       65.0         0          0
1      1    1        4      UA     DEN      IAD        823        7.0     154.0  1452       1333      -13.0         0          0
2      1    1        4      MQ     DFW      VPS       1305       36.0      85.0   641       1453       35.0         0          0
3      1    1        4      AA     DFW      DCA       1555        7.0     126.0  1192       1935       -7.0         0          0
4      1    1        4      WN     LAX      MCI       1720       48.0     166.0  1363       2225       39.0         0          0
5      1    1        4      UA     IAH      SAN       1450        1.0     178.0  1303       1620      -14.0         0          0
6      1    1        4      AA     DFW      MSY       1250       84.0      64.0   447       1410       83.0         0          0
7      1    1        4      F9     SFO      PHX       1020       -7.0      91.0   651       1315       -6.0         0          0
8      1    1        4      AA     ORD      STL       1845       -5.0      44.0   258       1950       -5.0         0          0
9      1    1        4      UA     IAH      SJC        925        3.0     215.0  1608       1136      -14.0         0          0

ORG_AIR  DEST_AIR
ATL      ABE         31
         ABQ         16
         ABY         19
         ACY          6
         AEX         40
         AGS         83
         ALB         33
         ANC          2
         ASE          1
         ATW         10
dtype: int64

ORG_AIR  DEST_AIR
ATL      IAH         121
IAH      ATL         148
dtype: int64

*** No columns names ***  Why?

0    [LAX, SLC]
1    [DEN, IAD]
2    [DFW, VPS]
3    [DCA, DFW]
4    [LAX, MCI]
5    [IAH, SAN]
6    [DFW, MSY]
7    [PHX, SFO]
8    [ORD, STL]
9    [IAH, SJC]
dtype: object

Выход автора. Обратите внимание, что имена столбцов присутствуют.

Df.apply(sorted, axis=1) удаляет имена столбцов?

Когда вы применяете отсортированную функцию, она дает объект серии (не фрейм данных) с тем же индексом, но список значений из каждой строки в отсортированном порядке. Другими словами, вы полностью отделили значения от их заголовков столбцов, отсортировав каждую строку независимо, сделав столбцы более неприменимыми.

G. Anderson 29.05.2019 00:44

@ G.Anderson, Хм .. Авторы показывают вывод, который я скопировал для этой точной строки кода. Я не сомневаюсь в вашем ответе, учитывая то, что я вижу. Как я могу исправить проблему. Я пробовал: рейсы_sort = рейсы.sort_values(by=['ORG_AIR', 'DEST_AIR'], axis=1), но это также дает мне KeyError. Обратите внимание, что если я избавлюсь от оси = 1, он будет работать без ошибок, но я не получу желаемого результата.

MarkS 29.05.2019 00:49

Угу. Это нехорошо. Я настоятельно рекомендую книгу Уэса Python для анализа данных.

Andy Hayden 29.05.2019 01:11
Почему в Python есть оператор "pass"?
Почему в Python есть оператор "pass"?
Оператор pass в Python - это простая концепция, которую могут быстро освоить даже новички без опыта программирования.
Некоторые методы, о которых вы не знали, что они существуют в Python
Некоторые методы, о которых вы не знали, что они существуют в Python
Python - самый известный и самый простой в изучении язык в наши дни. Имея широкий спектр применения в области машинного обучения, Data Science,...
Основы Python Часть I
Основы Python Часть I
Вы когда-нибудь задумывались, почему в программах на Python вы видите приведенный ниже код?
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
Алиса и Боб имеют неориентированный граф из n узлов и трех типов ребер:
Оптимизация кода с помощью тернарного оператора Python
Оптимизация кода с помощью тернарного оператора Python
И последнее, что мы хотели бы показать вам, прежде чем двигаться дальше, это
Советы по эффективной веб-разработке с помощью Python
Советы по эффективной веб-разработке с помощью Python
Как веб-разработчик, Python может стать мощным инструментом для создания эффективных и масштабируемых веб-приложений.
1
3
273
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Ответ принят как подходящий

отсортированный возвращает объект списка и стирает столбцы:

In [11]: df = pd.DataFrame([[1, 2], [3, 4]], columns=["A", "B"])

In [12]: df.apply(sorted, axis=1)
Out[12]:
0    [1, 2]
1    [3, 4]
dtype: object

In [13]: type(df.apply(sorted, axis=1).iloc[0])
Out[13]: list

Возможно, в более ранних пандах этого не было... но это все равно был бы плохой код.

Вы можете сделать это, передав столбцы явно:

In [14]: df.apply(lambda x: pd.Series(sorted(x), df.columns), axis=1)
Out[14]:
   A  B
0  1  2
1  3  4

Более эффективный способ сделать это - отсортировать базовый массив numpy:

In [21]: df = pd.DataFrame([[1, 2], [3, 1]], columns=["A", "B"])

In [22]: df
Out[22]:
   A  B
0  1  2
1  3  1

In [23]: arr = df[["A", "B"]].values

In [24]: arr.sort(axis=1)

In [25]: df[["A", "B"]] = arr

In [26]: df
Out[26]:
   A  B
0  1  2
1  1  3

Как видите, это сортирует каждый ряд.

В сторону: я очень рекомендую книгу Уэса Python для анализа данных.

Andy Hayden 29.05.2019 01:13

Но у меня все еще есть основная проблема. Я не могу использовать «rename_dict», потому что моя первая сортировка стирает имена столбцов. Как правильно отсортировать фрейм данных по столбцу, чтобы применить переименование?

MarkS 29.05.2019 01:15

@MarkS О, я вижу, что они пытаются сделать. Используйте df.apply(lambda x: pd.Series(sorted(x), df.columns), axis=1)

Andy Hayden 29.05.2019 01:18

Когда я пытаюсь: рейсы_sort = рейсы.apply(лямбда x: pd.Series(отсортировано(х), рейсы.столбцы), оси=1), я получаю это: flights_sort = flights.apply(lambda x: pd.Series(sorted(x), flights.columns), axis=1) TypeError: ("'<' not supported between instances of 'str' and 'int'", 'occurred at index 0')

MarkS 29.05.2019 01:22

@MarkS просто сделайте это для этих столбцов df[['ORG_AIR', 'DEST_AIR']].apply(lambda x: pd.Series(sorted(x), df.columns), axis=1)

Andy Hayden 29.05.2019 01:23

Изменение на это: Flight_sort = рейсы[['ORG_AIR', 'DEST_AIR']].apply(лямбда x: pd.Series(sorted(x), Flights.columns), ось=1), дает это: ValueError: ('Length of passed values is 2, index implies 14', 'occurred at index 0')

MarkS 29.05.2019 01:30

@MarkS sort = рейсы[['ORG_AIR', 'DEST_AIR']].apply(лямбда x: pd.Series(sorted(x), ['ORG_AIR', 'DEST_AIR']), ось=1)

Andy Hayden 29.05.2019 01:30

@MarkS это потому, что вы сортируете только эти два столбца, а не всю строку.

Andy Hayden 29.05.2019 01:31

Теперь я получаю точный вывод, который получает автор. Если будешь рядом с Индианаполисом, найди меня. Я покупаю. Я также принял вашу последнюю запись как правильный ответ.

MarkS 29.05.2019 01:34

Последнее замечание. Я только что применил решение на основе numpy @AndyHayden сверху.

flights_sort = flights[["ORG_AIR", "DEST_AIR"]].values
flights_sort.sort(axis=1)
flights[["ORG_AIR", "DEST_AIR"]] = flights_sort

Все, что я могу сказать, это… Ничего себе. Какая огромная разница в производительности. я получаю то же самое правильный ответ, и я получаю его, как только щелкаю мышью, по сравнению с лямбда-решением pandas, также предоставленным @AndyHayden, которое занимает около 20 секунд для выполнения сортировки. Этот набор данных содержит более 58 000 строк. Решение numpy мгновенно возвращает сортировку.

.apply медленный... .apply медленный. Повторяйте за мной: .apply медленно. Это должно быть решением последней инстанции, и, по сути, это обычный старый цикл for под капотом.
juanpa.arrivillaga 29.05.2019 19:36

Другие вопросы по теме