Python 熊猫基于df1中表示df2间隔的列检索值

Python 熊猫基于df1中表示df2间隔的列检索值,python,pandas,dataframe,Python,Pandas,Dataframe,我有一个结构化的数据帧DF1: import pandas as pd df = pd.DataFrame({'id': [1, 2], 'name': ['A', 'B'], 'ex': ['A1', 'B1'], 'init': ['1,3,5,7,', '10,12,15,17,20,'], 'end':['2,4,6,8,', '15,18,21,24,32']}, columns=['id', 'name', 'ex', 'init', 'end']) print df id na

我有一个结构化的数据帧DF1:

import pandas as pd
df = pd.DataFrame({'id': [1, 2], 'name': ['A', 'B'], 'ex': ['A1', 'B1'], 'init': ['1,3,5,7,', '10,12,15,17,20,'], 'end':['2,4,6,8,', '15,18,21,24,32']}, columns=['id', 'name', 'ex', 'init', 'end'])
print df

id  name  ex   init               end
1    A    A1   1,3,5,7,           2,4,6,8,
2    B    B1   10,12,15,17,20,    15,18,21,24,32
...
init和end列表示间隔(init end),因此:A->(1,2)、(3,4)、(5,6)、(7,8)、B->(10,15)、(12,18)、(15,21)、(17,24)、(20,32),。。。 另一方面,还有另一个数据帧DF2也表示间隔:

import pandas as pd
df2 = pd.DataFrame({'id': [1, 2], 'init': ['3', '16'], 'end':['6', '22']}, columns=['id', 'init', 'end'])
print df2

id   init   end
1     3      6
2     16     22
...
是否有任何智能且有效的方法来检查DF1的哪些范围包含DF2中的范围?在本例中,输出将是一个新的DF3:

id  name  ex    ranges
1    A    A1  (3,4), (5,6)
2    B    B1  (12,18),(15,21),(17,24)

我对此有点困惑,希望能得到帮助。提前谢谢

以下是一个可能的解决方案:

import pandas as pd
df1 = pd.DataFrame({'id': [1, 2], 'name': ['A', 'B'], 'ex': ['A1', 'B1'], 'init': ['1,3,5,7,', '10,12,15,17,20,'], 'end':['2,4,6,8,', '15,18,21,24,32']}, columns=['id', 'name', 'ex', 'init', 'end'])
df2 = pd.DataFrame({'id': [1, 2], 'init': ['3', '16'], 'end':['6', '22']}, columns=['id', 'init', 'end'])

df1.set_index('id', inplace=True)
df2.set_index('id', inplace=True)

df = df1.copy()
df[['init2', 'end2']] = df2

# Per-row function
def proc_row(row):
    # Make list of int pairs
    intervs = zip(map(int, filter(None, row.init.split(','))), map(int, filter(None, row.end.split(','))))
    # Range object to check numbers are in interval - use xrange in Python 2
    r = range(int(row.init2), int(row.end2) + 1)
    # Discard pairs out of interval
    return list(filter(lambda interv: interv[0] in r or interv[1] in r, intervs))

# Process rows
df['ranges'] = df.apply(proc_row, axis=1)
# Drop unnecesary columns
for k in ['init', 'end', 'init2', 'end2']: del df[k]

print(df)
输出:

   name  ex                                    ranges
id
1     A  A1                          [(3, 4), (5, 6)]
2     B  B1  [(12, 18), (15, 21), (17, 24), (20, 32)]

这就是我要做的

df['init'],df['end']=df.init.str.split(','),df.end.str.split(',')
df
Out[1915]:
   id name  ex                    init                   end
0   1    A  A1          [1, 3, 5, 7]        [2, 4, 6, 8]
1   2    B  B1  [10, 12, 15, 17, 20]  [15, 18, 21, 24, 32]
s=df.init.str.len()
s
Out[1917]:
0    4
1    5
Name: init, dtype: int64


NewDF=pd.DataFrame({'id':df.id.repeat(s),'name':df.name.repeat(s),'ex':df.ex.repeat(s),'init':df.init.sum(),'end':df.end.sum()})
s2=NewDF.merge(df2.set_index('id').stack().reset_index(),on='id').loc[lambda x : (x['end']>=x[0])&(x[0]>=x['init'])]
s2['New']=tuple(zip(s2.init,s2.end))
s2.groupby(['ex','id']).New.apply(list)
Out[1943]: 
ex  id
A1  1                             [(3, 4), (5, 6)]
B1  2     [(12, 18), (15, 21), (17, 24), (20, 32)]
Name: New, dtype: object

对于id相同的行,
df1
中的
init
end
列只能与
df2
中的
init
end
列进行检查,对吗?(顺便说一句,第二行打印的
df2
应该以
id
2
开头,而不是
1
对吗?)Hello@jdehesa,是的,只检查了具有相同id的行。我修复了df2的id,感谢警告!在df2中,init=16,end=22,输出是如何得到这些区间的:(12,18),(15,21),(17,24)?(16,22)部分包含在这些区间中?数字总是整数?让我用一个真实的例子来检查!提前谢谢你!!