Python 将切片数据帧分配到另一个大小相同的切片数据帧中会产生:ValueError,与Series不兼容的索引器

Python 将切片数据帧分配到另一个大小相同的切片数据帧中会产生:ValueError,与Series不兼容的索引器,python,pandas,dataframe,Python,Pandas,Dataframe,我试图将标签从一个数据帧df2应用到另一个df1,这取决于一个数据帧的列中的另一个值,以在另一个数据帧中的一对列定义的间隔内着陆 这是密码 import pandas import numpy df1 = pandas.DataFrame( { 'a' : [1,2,3,4,5,6], 'b' : True } ) df2 = pandas.DataFrame( { 'c1':[ 2.0,3.1,5.2] , 'c2': [2.5,4.6,7.1] , 'l': ['x1','x2','x3'

我试图将标签从一个数据帧df2应用到另一个df1,这取决于一个数据帧的列中的另一个值,以在另一个数据帧中的一对列定义的间隔内着陆

这是密码

import pandas
import numpy

df1 = pandas.DataFrame( { 'a' : [1,2,3,4,5,6], 'b' : True } )
df2 = pandas.DataFrame( { 'c1':[ 2.0,3.1,5.2] , 'c2': [2.5,4.6,7.1] , 'l': ['x1','x2','x3'] } )

df1['l'] = numpy.NaN

for i in range( len( df1 ) ) :
    aVal = df1.loc[ df1.index[i] , 'a' ]
    is_in_c1c2 = ( df2['c1'] <= aVal ) & ( aVal < df2['c2'] )

    if is_in_c1c2.any() :
        df1.loc[ df1.index[i], 'l' ] = numpy.squeeze( df2.loc[ is_in_c1c2 , 'l' ].values )

        # df1.loc[ df1.index[i], 'l' ] = df2.loc[ is_in_c1c2 , 'l' ] # ValueError, Incompatible indexer with Series


print( df1 )
print( df1['l'].map(type) )

>>>
   a     b    l
0  1  True  NaN
1  2  True   x1
2  3  True  NaN
3  4  True   x2
4  5  True  NaN
5  6  True   x3
0            <type 'float'>
1    <type 'numpy.ndarray'>
2            <type 'float'>
3    <type 'numpy.ndarray'>
4            <type 'float'>
5    <type 'numpy.ndarray'>
Name: l, dtype: object
我第一次尝试ValueError时意外地发现了异常,它是与Series不兼容的索引器。为什么不支持这一点?这是数据帧索引不匹配的结果还是什么


是否有更干净/矢量化的方法来执行此类操作?.values赋值很接近,但给我留下了错误的元素类型,所以我不得不压缩它们。在这里获得基本类型会很好。我还为一个专栏做了一个例子,但实际上我是在复制源代码中两个专栏的标签。

一种方法是使用Pandas的IntervalIndex

不知道这有多快。如果df1['a']真的只包含整数,那么有一种更快的方法


我认为您最初的ValueError是因为df2.loc[is_in_c1c2,'l']返回一个序列。尝试将序列指定为数据帧中的值时出错。和df2.loc[is_in_c1c2,'l']。值返回一个ndarray。数组只包含一个值,因为只有一个匹配项,但理论上可能有多个匹配项

你的问题中的输出是正确的输出吗,仅仅是混乱的类型?哎哟,这是应用numpy之前的输出。挤压我一定是错误地抓住了早期的控制台输出。这对我来说是熊猫空间中的一个伟大发现,从来都不知道这些逻辑的间隔位。这里有一个全新的研究领域,谢谢你的建议。即使同时使用多个“l”列,也能像符咒一样发挥作用。
idx = pd.IntervalIndex.from_arrays(df2['c1'], df2['c2'], closed='both')
df1['l'] = df2.loc[idx.get_indexer(df1['a']), 'l'].values
df1
>>>
    a   b       l
0   1   True    NaN
1   2   True    x1
2   3   True    NaN
3   4   True    x2
4   5   True    NaN
5   6   True    x3