Работаем через 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
Выход автора. Обратите внимание, что имена столбцов присутствуют.
@ G.Anderson, Хм .. Авторы показывают вывод, который я скопировал для этой точной строки кода. Я не сомневаюсь в вашем ответе, учитывая то, что я вижу. Как я могу исправить проблему. Я пробовал: рейсы_sort = рейсы.sort_values(by=['ORG_AIR', 'DEST_AIR'], axis=1), но это также дает мне KeyError. Обратите внимание, что если я избавлюсь от оси = 1, он будет работать без ошибок, но я не получу желаемого результата.
Угу. Это нехорошо. Я настоятельно рекомендую книгу Уэса Python для анализа данных.
отсортированный возвращает объект списка и стирает столбцы:
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 для анализа данных.
Но у меня все еще есть основная проблема. Я не могу использовать «rename_dict», потому что моя первая сортировка стирает имена столбцов. Как правильно отсортировать фрейм данных по столбцу, чтобы применить переименование?
@MarkS О, я вижу, что они пытаются сделать. Используйте df.apply(lambda x: pd.Series(sorted(x), df.columns), axis=1)
Когда я пытаюсь: рейсы_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 просто сделайте это для этих столбцов df[['ORG_AIR', 'DEST_AIR']].apply(lambda x: pd.Series(sorted(x), df.columns), axis=1)
Изменение на это: 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 sort = рейсы[['ORG_AIR', 'DEST_AIR']].apply(лямбда x: pd.Series(sorted(x), ['ORG_AIR', 'DEST_AIR']), ось=1)
@MarkS это потому, что вы сортируете только эти два столбца, а не всю строку.
Теперь я получаю точный вывод, который получает автор. Если будешь рядом с Индианаполисом, найди меня. Я покупаю. Я также принял вашу последнюю запись как правильный ответ.
Последнее замечание. Я только что применил решение на основе 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 под капотом.
Когда вы применяете отсортированную функцию, она дает объект серии (не фрейм данных) с тем же индексом, но список значений из каждой строки в отсортированном порядке. Другими словами, вы полностью отделили значения от их заголовков столбцов, отсортировав каждую строку независимо, сделав столбцы более неприменимыми.