按pandas中的值对数据进行分类

swe*_*eet 5 python pandas

我有一个pandas.DataFrame表格

low_bound   high_bound   name
0           10           'a'
10          20           'b'
20          30           'c'
30          40           'd'
40          50           'e'
Run Code Online (Sandbox Code Playgroud)

我有一个很长 pandas.Series的形式:

value
5.7
30.4
21
35.1
Run Code Online (Sandbox Code Playgroud)

我想为系列的每个值赋予与low_bound/high_bound/name DataFrame相关的相应名称.这是我的预期结果:

value         name
5.7           'a'
30.4          'd'
21            'c'
35.1          'd'
Run Code Online (Sandbox Code Playgroud)

实际上,5.7名称是'a',因为5.7被排除在0到10之间.

什么是最有效的代码?我知道我可以通过迭代系列来解决问题,但也许有一个更快的矢量解决方案可以逃避我.

最后请注意我的界限可以是自定义和不规则的.为了这个例子,他们在这里是常规的.

Sim*_*mon 7

Pandas 有一个方法cut可以做你想做的事:

import pandas as pd

data = [{"low": 0, "high": 10, "name": "a"},
        {"low": 10, "high": 20, "name": "b"},
        {"low": 20, "high": 30, "name": "c"},
        {"low": 30, "high": 40, "name": "d"},
        {"low": 40, "high": 50, "name": "e"},]

myDF = pd.DataFrame(data)

#data to be binned
mySeries = pd.Series([5.7, 30.4, 21, 35.1])

#create bins from original data
bins = list(myDF["high"])
bins.insert(0,0)

print pd.cut(mySeries, bins, labels = myDF["name"])
Run Code Online (Sandbox Code Playgroud)

这将为您提供以下内容,然后您可以将其放回某个数据框中,或者您想要保存数据:

0    a
1    d
2    c
3    d
dtype: category
Categories (5, object): [a < b < c < d < e]
Run Code Online (Sandbox Code Playgroud)

根据您的垃圾箱的不规则程度(以及您所说的自定义/不规则的确切含义),您可能不得不求助于遍历系列。我想不出我的头顶会为你处理这个问题,特别是考虑到它取决于垃圾箱中不规则的程度/类型。

循环明智,如果您有下限和上限,则此方法将起作用,而不管“规则性”如何:

for el in mySeries:
    print myDF["name"][(myDF["low"] < el) & (myDF["high"] > el)]
Run Code Online (Sandbox Code Playgroud)

我很欣赏你可能不想遍历一个巨大的系列,但至少我们没有手动索引数据帧,这可能会使事情变得更慢