映射pandas dataframe

时间:2018-04-30 09:52:16

标签: python pandas dataframe

如果之前有人问过这个问题,我会道歉,但我看起来很普遍而没有结果。

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})

2 个答案:

答案 0 :(得分:8)

有一些替代方案。

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

您可以构建边界列表,然后使用专业库函数。这在@EdChum's solution以及this 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的元素是布尔系列,因此对于值的列表,您可以使用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

答案 1 :(得分:7)

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}}给他们

在这里你可以看到如何计算削减:

+1