【问题标题】:Mapping ranges of values in pandas dataframe [duplicate]熊猫数据框中值的映射范围[重复]
【发布时间】:2018-10-10 09:38:55
【问题描述】:

抱歉,如果以前有人问过这个问题,但我看了很多,没有结果。

import pandas as pd    
import numpy as np    
df = pd.DataFrame(data = np.random.randint(1,10,10),columns=['a'])    

   a
0  7
1  8
2  8
3  3
4  1
5  1
6  2
7  8
8  6
9  6

我想创建一个新列b,它根据某些规则映射a 的多个值,例如 a=[1,2,3] 为 1,a = [4,5,6, 7] 是 2,a = [8,9,10] 是 3。一对一的映射对我来说很清楚,但是如果我想按值列表或范围进行映射呢?

我沿着这些路线坚持...

df['b'] = df['a'].map({[1,2,3]:1,range(4,7):2,[8,9,10]:3})

【问题讨论】:

  • 将该映射转换为一对一映射应该不难。您目前如何存储这些地图数据?
  • 到目前为止,我像上面一样插入了字典'by hand',因为映射相对简单。但我也可以事先定义字典。我意识到可以很容易地做到这一点,但是如果我想将值 [50..150] 映射到某个值呢?
  • 那不是一本有效的字典。如果您有类似键值对的元组 [([1, 2, 3], 1), (range(4, 7), 2), ([8, 9, 10], 3)] ,您可以遍历列表并生成一对一的映射,但您需要先确定您的数据结构。
  • 如果这是特定于范围,而不是任意数字集合,您可能需要查看pd.cut

标签: python pandas dataframe categories binning


【解决方案1】:

有几种选择。

Pandas 通过pd.cut / NumPy 通过np.digitize

您可以构建一个边界列表,然后使用专业的库函数。这在@EdChum's solutionthis answer 中有描述。

NumPy 通过np.select

df = pd.DataFrame(data=np.random.randint(1,10,10), columns=['a'])

criteria = [df['a'].between(1, 3), df['a'].between(4, 7), df['a'].between(8, 10)]
values = [1, 2, 3]

df['b'] = np.select(criteria, values, 0)

criteria的元素是布尔系列,所以对于lists的值,可以使用df['a'].isin([1, 3])

字典映射通过range

d = {range(1, 4): 1, range(4, 8): 2, range(8, 11): 3}

df['c'] = df['a'].apply(lambda x: next((v for k, v in d.items() if x in k), 0))

print(df)

   a  b  c
0  1  1  1
1  7  2  2
2  5  2  2
3  1  1  1
4  3  1  1
5  5  2  2
6  4  2  2
7  4  2  2
8  9  3  3
9  3  1  1

【讨论】:

  • 浮点值怎么样 我尝试使用字典映射,但它不适用于数据框中的浮点值,它只对整数进行分类
  • @AHR,在这种情况下使用np.select,字典方法将不起作用。
【解决方案2】:

IIUC 你可以使用cut 来实现:

In[33]:
pd.cut(df['a'], bins=[0,3,7,11], right=True, labels=False)+1

Out[33]: 
0    2
1    3
2    3
3    1
4    1
5    1
6    1
7    3
8    2
9    2

在这里,您可以将截止值传递给cut,这将对您的值进行分类,通过传递labels=False,它将给它们一个序数值(从零开始),因此您只需将+1 传递给它们

您可以在此处查看削减的计算方式:

In[34]:
pd.cut(df['a'], bins=[0,3,7,11], right=True)

Out[34]: 
0     (3, 7]
1    (7, 11]
2    (7, 11]
3     (0, 3]
4     (0, 3]
5     (0, 3]
6     (0, 3]
7    (7, 11]
8     (3, 7]
9     (3, 7]
Name: a, dtype: category
Categories (3, interval[int64]): [(0, 3] < (3, 7] < (7, 11]]

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2019-07-12
    • 2019-11-15
    • 1970-01-01
    • 2022-01-06
    • 1970-01-01
    • 1970-01-01
    • 2017-11-30
    相关资源
    最近更新 更多