Python 应用行特定条件的有效方法
我有出境航班的数据,包括日期、月份、机场等信息。 我想通过这些行,并为每一行计算+-15m内从同一机场起飞的航班数量。 我的代码似乎可以工作,但速度非常慢(在10万行上,运行大约需要一个小时)。 有没有办法提高它的效率? 这是一个示例文件 谢谢Python 应用行特定条件的有效方法,python,pandas,Python,Pandas,我有出境航班的数据,包括日期、月份、机场等信息。 我想通过这些行,并为每一行计算+-15m内从同一机场起飞的航班数量。 我的代码似乎可以工作,但速度非常慢(在10万行上,运行大约需要一个小时)。 有没有办法提高它的效率? 这是一个示例文件 谢谢 time\u余量=15 收尾=[] i=0 对于索引,df.iterrows()中的行: i+=1 idf=df.loc[(df['Origin']==行['Origin'])& (df['Month']==行['Month'])& (df['Dayof
time\u余量=15
收尾=[]
i=0
对于索引,df.iterrows()中的行:
i+=1
idf=df.loc[(df['Origin']==行['Origin'])&
(df['Month']==行['Month'])&
(df['DayofMonth']==行['DayofMonth'])&
(df['DepTime']<行['DepTime']+时间容差)&
(df['DepTime']>行['DepTime']-时间津贴),:]
结束。追加(len(idf))
col_name=‘收尾’+str(时间容差)
df[col\u name]=结束
您的代码
仅使用
groupby
和apply
方法进行一些基本改进。
仅按某些字段分组,就可以看到大约34%的改进
改进性能的下一步
有两个主要的选择:
- 继续改进算法的性能
- 并行化
这是另一种选择。另一个更高层次的抽象选项是。你能添加一些样本数据吗?我想我应该
将索引设置为datetime,groupby
原点,并应用+/-15分钟的滚动窗口对组进行迭代。。。不过,一杯就好了…@jezrael加了一句linkWow,酷!还有其他关于提高效率的想法吗?非常感谢您的工作代码,但是如果您向我指出一些方向,那也很好(我不想浪费您太多的时间来编写我的代码:))我将编辑我的答案,添加一些指导原则,以继续提高性能@StanislavNosulenkoI我猜这就结束了-我将尽可能地实现这一点:)谢谢@BSP!
time_allowance = 15
close_out = []
i=0
for index, row in df.iterrows():
i+=1
idf = df.loc[(df['Origin'] == row['Origin']) &
(df['Month'] == row['Month']) &
(df['DayofMonth'] == row['DayofMonth']) &
(df['DepTime'] < row['DepTime'] + time_allowance) &
(df['DepTime'] > row['DepTime'] - time_allowance), :]
close_out.append(len(idf))
col_name = 'close_out' + str(time_allowance)
df[col_name] = close_out
import pandas as pd
cols = ['Month', 'DayofMonth', 'DayOfWeek', 'DepTime', 'UniqueCarrier', 'Origin', 'Dest', 'Distance']
data = [
['c-8', 'c-21', 'c-7', 1934, 'AA', 'ATL', 'DFW', 732],
['c-6', 'c-19', 'c-2', 1942, 'AA', 'ATL', 'CLE', 999],
['c-6', 'c-19', 'c-2', 1955, 'AA', 'ATL', 'CLE', 111],
['c-4', 'c-20', 'c-3', 1548, 'US', 'PIT', 'MCO', 834],
['c-9', 'c-2', 'c-5', 1422, 'XE', 'RDU', 'CLE', 416],
['c-11', 'c-25', 'c-6', 1015, 'OO', 'DEN', 'MEM', 872],
['c-10', 'c-7', 'c-6', 1828, 'WN', 'MDW', 'OMA', 423]
]
df = pd.DataFrame(data=data, columns=cols)
df['close_out15'] = 0
def algo_v1(df):
time_allowance = 15
close_out = []
i=0
for index, row in df.iterrows():
i+=1
idf = df.loc[(df['Origin'] == row['Origin']) &
(df['Month'] == row['Month']) &
(df['DayofMonth'] == row['DayofMonth']) &
(df['DepTime'] < row['DepTime'] + time_allowance) &
(df['DepTime'] > row['DepTime'] - time_allowance), :]
close_out.append(len(idf))
col_name = 'close_out' + str(time_allowance)
df[col_name] = close_out
return df
#print(algo_v1(df))
#%timeit algo_v1(df)
Month DayofMonth DayOfWeek DepTime ... Origin Dest Distance close_out15
0 c-8 c-21 c-7 1934 ... ATL DFW 732 1
1 c-6 c-19 c-2 1942 ... ATL CLE 999 2
2 c-6 c-19 c-2 1955 ... ATL CLE 111 2
3 c-4 c-20 c-3 1548 ... PIT MCO 834 1
4 c-9 c-2 c-5 1422 ... RDU CLE 416 1
5 c-11 c-25 c-6 1015 ... DEN MEM 872 1
6 c-10 c-7 c-6 1828 ... MDW OMA 423 1
[7 rows x 9 columns]
10 loops, best of 3: 28.4 ms per loop
def filter_and_count(df):
time_threshold = 15
for idx, row in df.iterrows():
row['close_out15'] = df['UniqueCarrier'].loc[
(df['DepTime'] <= row['DepTime'] + time_threshold)
& (df['DepTime'] >= row['DepTime'] - time_threshold)
].count()
def algo_v2(df):
df.groupby(['Origin', 'Month', 'DayofMonth']).apply(filter_and_count)
return df
#print(algo_v2(df))
#%timeit algo_v2(df)
Month DayofMonth DayOfWeek DepTime ... Origin Dest Distance close_out15
0 c-8 c-21 c-7 1934 ... ATL DFW 732 1
1 c-6 c-19 c-2 1942 ... ATL CLE 999 2
2 c-6 c-19 c-2 1955 ... ATL CLE 111 2
3 c-4 c-20 c-3 1548 ... PIT MCO 834 1
4 c-9 c-2 c-5 1422 ... RDU CLE 416 1
5 c-11 c-25 c-6 1015 ... DEN MEM 872 1
6 c-10 c-7 c-6 1828 ... MDW OMA 423 1
[7 rows x 9 columns]
100 loops, best of 3: 18.8 ms per loop