根据另一个数据框中行的范围添加/填充熊猫列

时间:2018-08-02 23:50:34

标签: python pandas

与大熊猫一起工作,我用时间样本对df1进行了索引:

data = '''\
time       flags    input                  
8228835.0  53153.0  32768.0
8228837.0  53153.0  32768.0
8228839.0  53153.0  32768.0
8228841.0  53153.0  32768.0
8228843.0  61345.0  32768.0'''

fileobj = pd.compat.StringIO(data)
df1 = pd.read_csv(fileobj, sep='\s+', index_col='time')

df2用开始和结束指示时间范围,以定义“ check”状态为True的范围:

data = '''\
        check     start       end
20536   True   8228837   8228993
20576   True   8232747   8232869
20554   True   8230621   8230761
20520   True   8227351   8227507
20480   True   8223549   8223669
20471   True   8221391   8221553'''

fileobj = pd.compat.StringIO(data)
df2 = pd.read_csv(fileobj, sep='\s+')

我需要做的是在df1中添加一列“检查”,并用True值填充df2中定义的实际时间范围。所有其他人都应该是错误的。结果示例如下:

             flags    input    check
time                       
8228835.0  53153.0  32768.0    False
8228837.0  53153.0  32768.0    True
8228839.0  53153.0  32768.0    True
8228841.0  53153.0  32768.0    True
8228843.0  61345.0  32768.0    True
....
8228994.0. 12424.0. 32768.0.   False

3 个答案:

答案 0 :(得分:2)

您可以创建一个列表或范围,然后将pd.Index.isinitertools.chain结合使用:

from itertools import chain

df2 = df2[df2['check'] == True]

ranges = [range(i, j) for i, j in zip(df2['start'], df2['end'])] #missing single quote

df.loc[df.index.isin(ranges), 'check'] = True

print(df1)

             flags    input  check
time                              
8228835.0  53153.0  32768.0  False
8228837.0  53153.0  32768.0   True
8228839.0  53153.0  32768.0   True
8228841.0  53153.0  32768.0   True
8228843.0  61345.0  32768.0   True

答案 1 :(得分:1)

我认为您可以将IntervalIndexloc一起使用

df2.index=pd.IntervalIndex.from_arrays(df2.start,df2.end,'both')
df2.loc[df.index]
Out[174]: 
        check  start  end
[1, 2]   True      1    2
[4, 5]   True      4    5
[7, 8]   True      7    8
df['newcol']=df2.loc[df.index].check.values.tolist()
df
Out[176]: 
       flags    input  newcol
flags                        
2          2  32768.0    True
4          4  32768.0    True
7          7  32768.0    True

答案 2 :(得分:0)

使用any()进行列表理解。不过,如果您可以为我们运行%timing,那么对实际性能没有任何了解!

df1['check'] = [any(start <= i <= end for start,end in 
                    zip(df2['start'], df2['end'])) for i in df1.index]

print(df1)

返回:

             flags    input  check
time                              
8228835.0  53153.0  32768.0  False
8228837.0  53153.0  32768.0   True
8228839.0  53153.0  32768.0   True
8228841.0  53153.0  32768.0   True
8228843.0  61345.0  32768.0   True