在两列python dataframe中搜索范围内的特定值

时间:2017-12-22 11:55:20

标签: python pandas dataframe lookup

我有两个csv文件。根据csv文件1中单元格的值,我应该能够在csv文件2的列中搜索该值,并从csv文件2中的其他列获取相应的值。 如果这很令人困惑,我很抱歉。它可能会通过插图得到清楚

CSV文件1

Car   Mileage
 A       8
 B       6
 C       10

CSV文件2

Score  Mileage(Min)    Mileage(Max)
 1       1                 3
 2       4                 6
 3       7                 9
 4       10                12 
 5       13                15 

我想要的输出CSV文件是这样的

Car    Mileage     Score
 A       8           3
 B       6           2
 C       10          4

A车的得分为3,具体取决于其里程数8,然后在csv文件2中查看其里程范围内的里程数,然后获得该范围的相应得分值。 任何帮助将不胜感激 提前致谢

3 个答案:

答案 0 :(得分:3)

  

截至编写本文时,当前稳定版本为v0.21。

要阅读文件,请使用pd.read_csv -

df0 = pd.read_csv('file1.csv')
df1 = pd.read_csv('file2.csv')

df0

  Car  Mileage
0   A        8
1   B        6
2   C       10

df1

   Score  Mileage(Min)  Mileage(Max)
0      1             1             3
1      2             4             6
2      3             7             9
3      4            10            12
4      5            13            15

要查找分数,请致电IntervalIndex.from_tuples使用pd.IntervalIndex。这应该非常快 -

v = df1.loc[:, 'Mileage(Min)':'Mileage(Max)'].apply(tuple, 1).tolist()
idx = pd.IntervalIndex.from_tuples(v, closed='both') # you can also use `from_arrays`


df0['Score'] = df1.iloc[idx.get_indexer(df0.Mileage.values), 'Score'].values
df0

  Car  Mileage  Score
0   A        8      3
1   B        6      2
2   C       10      4

其他创建IntervalIndex的方法概述为here

要编写结果,请使用pd.DataFrame.to_csv -

df0.to_csv('file3.csv')

这是我在这里所做的高级概述。

  1. 首先,读入您的CSV文件
  2. 使用pd.IntervalIndex构建区间索引。因此,现在搜索的复杂程度是对数。
  3. 使用idx.get_indexer查找树中每个值的索引
  4. 使用索引在Score中找到df1值,并将其分配回df0。请注意,我调用了.values,否则,在分配回来时,这些值将会错位。
  5. 将结果写回CSV
  6. 有关Intervalindex的更多信息,请查看此SO Q / A - Finding matching interval(s) in pandas Intervalindex

    请注意,IntervalIndexv0.20中的新内容,因此如果您使用的是旧版本,请务必使用

    更新您的版本
    pip install --upgrade pandas
    

答案 1 :(得分:1)

您可以使用版本0.20.0+中新增的IntervalIndex

首先按read_csv创建DataFrame:

df1 = pd.read_csv('file1.csv')
df2 = pd.read_csv('file2.csv')

from_arrays创建IntervalIndex

s = pd.IntervalIndex.from_arrays(df2['Mileage(Min)'], df2['Mileage(Max)'], 'both')

print (s)
IntervalIndex([[1, 3], [4, 6], [7, 9], [10, 12], [13, 15]]
              closed='both',
              dtype='interval[int64]')

按intervalindex选择Mileage值,并按values创建的数组设置为新列,因为其他索引未对齐且得到:

  

TypeError:带有帧索引的插入列的不兼容索引

df1['Score'] = df2.set_index(s).loc[df1['Mileage'], 'Score'].values
print (df1)
  Car  Mileage  Score
0   A        8      3
1   B        6      2
2   C       10      4

最后由to_csv写入文件:

df1.to_csv('file3.csv', index=False)

答案 2 :(得分:0)

设置

data  = [(1,1,3), (2,4,6), (3,7,9), (4,10,12), (5,13,15)]
df = pd.DataFrame(data, columns=['Score','MMin','MMax'])

car_data = [('A', 8), ('B', 6), ('C', 10)]
car = pd.DataFrame(car_data, columns=['Car','Mileage'])

def find_score(x, df):
    result = -99
    for idx, row in df.iterrows():
        if x >= row.MMin and x <= row.MMax:
            result = row.Score
    return result

car['Score'] = car.Mileage.apply(lambda x: find_score(x, df))

哪个收益

In [58]: car
Out[58]:
  Car  Mileage  Score
0   A        8      3
1   B        6      2
2   C       10      4