Python 如何矢量化(使用Numpy/Pandas)嵌套for循环下的嵌套if语句

Python 如何矢量化(使用Numpy/Pandas)嵌套for循环下的嵌套if语句,python,pandas,numpy,vectorization,nested-loops,Python,Pandas,Numpy,Vectorization,Nested Loops,我试图比较两个数据帧,我希望有效地使用pandas(或numpy)而不是嵌套的for循环,其中包含if语句来解决特定问题。下面是我的程序的一个小嗅探器 spindleload = {'time': ['2020-02-03 00:18:07', '2020-02-03 00:18:08', '2020-02-03 00:18:09', '2020-02-03 00:18:10', '2020-02-03 00:18:11', '2020-02-03 00:18:12', '2020-02-03

我试图比较两个数据帧,我希望有效地使用
pandas(或numpy)
而不是嵌套的for循环,其中包含if语句来解决特定问题。下面是我的程序的一个小嗅探器

spindleload = {'time': ['2020-02-03 00:18:07', '2020-02-03 00:18:08', '2020-02-03 00:18:09', '2020-02-03 00:18:10', '2020-02-03 00:18:11', '2020-02-03 00:18:12', '2020-02-03 00:18:13', '2020-02-03 00:18:14', '2020-02-03 00:18:15', '2020-02-03 00:18:16', '2020-02-03 00:18:17'], 
               'value': [17,25,14,14,22,22,22,22,22,12,19]}
df1 = pd.DataFrame(data=spindleload) 


cycletime = {'newtimestart': ['2020-02-03 00:18:08','2020-02-03 00:18:13'], 'newtimeend': ['2020-02-03 00:18:11', '2020-02-03 00:18:15']}
df2 = pd.DataFrame(data=cycletime)
现在,我希望循环它以获得df1中的timevalue以及df2newtimestartnewtimeend之间的相应值。下面是代码

output_graph_time = []
output_graph_value = []

for i in range(len(df2)):
    for j in range(len(df1)):
        if df1['time'][j] >= df2['newtimestart'][i]:
            output_graph_time.append(df1['time'][j])
            output_graph_value.append(df1['value'][j])  
            if df1['time'][j] == df2['newtimeend'][i]:
                break
print(output_graph_time)
print(output_graph_value)
现在代码工作正常,但当它读取数百万行数据时无法执行,我也尝试实现
Numba
,但内核无法处理并用于重新启动。 因此,我要求使用NumpyPandas矢量化方法来解决这个问题


此外,当我尝试应用矢量化方法时,我发现每次执行后都很难打破if条件。

您可以在日期范围内转换df2并分解,然后使用
isin
过滤器df1

从字符串转换为日期时间(忽略此步骤,因为值已经是日期时间)

映射为
pd.date\u范围
分解
,然后使用
isin进行过滤

out = (df1[df1['time'].isin(df2.agg(tuple,1).map(lambda x: 
                  pd.date_range(*x,freq='s')).explode())])

这与您的输出类似:

print(output_graph_time)
print(output_graph_value)

['2020-02-03 00:18:08', '2020-02-03 00:18:09', '2020-02-03 00:18:10', 
'2020-02-03 00:18:11', '2020-02-03 00:18:13', '2020-02-03 00:18:14', 
 '2020-02-03 00:18:15']

[25, 14, 14, 22, 22, 22, 22]

您可以在日期范围内转换df2并分解,然后使用
isin
filter df1

从字符串转换为日期时间(忽略此步骤,因为值已经是日期时间)

映射为
pd.date\u范围
分解
,然后使用
isin进行过滤

out = (df1[df1['time'].isin(df2.agg(tuple,1).map(lambda x: 
                  pd.date_range(*x,freq='s')).explode())])

这与您的输出类似:

print(output_graph_time)
print(output_graph_value)

['2020-02-03 00:18:08', '2020-02-03 00:18:09', '2020-02-03 00:18:10', 
'2020-02-03 00:18:11', '2020-02-03 00:18:13', '2020-02-03 00:18:14', 
 '2020-02-03 00:18:15']

[25, 14, 14, 22, 22, 22, 22]

我知道
df1
是数百万行。如果您的
df2
不是太大,您可以执行交叉合并:

(df1.assign(dummy=1)
    .merge(df2.assign(dummy=1), on='dummy')
    .query('newtimestart<=time<=newtimeend')
)

我知道
df1
是数百万行。如果您的
df2
不是太大,您可以执行交叉合并:

(df1.assign(dummy=1)
    .merge(df2.assign(dummy=1), on='dummy')
    .query('newtimestart<=time<=newtimeend')
)