大熊猫栏目的不平等

时间:2017-07-05 21:13:31

标签: python pandas dataframe

我有一个pandas数据框,我想基于现有列和某些不等式创建一个新列。例如,让

df=pd.DataFrame({'a':[1,2,3,4,5,6,7],'b':[3,6,4,2,7,7,1]})

所以df看起来像

    a   b
0   1   3
1   2   6
2   3   4
3   4   2
4   5   7
5   6   7
6   7   1

我想添加一个新列res,如果a中的对应值小于2则等于0,如果a中的对应值至少为1 2小于4,否则为2。所以我想得到

    a   b   res
0   1   3   0
1   2   6   1
2   3   4   1
3   4   2   2
4   5   7   2
5   6   7   2
6   7   1   2

到目前为止,我一直使用apply执行此操作,如下所示:

def f(x):
    if x['a']<2:
        return 0
    elif x['a']>=2 and x['a']<4:
        return 1
    else:
        return 2
df['res']=df.apply(f,axis=1)

但我想知道是否有更直接的方法,或者某些特定的熊猫方法可以让我这样做。

3 个答案:

答案 0 :(得分:5)

您可以使用pd.cut

GridContextMenu<Project> contextMenu = new GridContextMenu<>(treeGrid);
contextMenu.addGridBodyContextMenuListener(contextEvent -> {
    contextMenu.removeItems();
    if (contextEvent.getItem() != null) {
        Project project = (Project) contextEvent.getItem();
        // update selection
        treeGrid.select(project);

        // show option for expanding
        contextMenu.addItem("Expand all", VaadinIcons.PLUS, event -> treeGrid.expand((project).flatten().collect(Collectors.toList())));

        // show option for collapsing
        contextMenu.addItem("Collapse all", VaadinIcons.MINUS, event -> treeGrid.collapse((project).flatten().collect(Collectors.toList())));
    }
});

输出:

df['res'] = pd.cut(df.a,[-np.inf,2,4,np.inf],labels=[0,1,2],right=False)

答案 1 :(得分:3)

只需几个值,您还可以使用numpy.where作为矢量化解决方案:

df['res'] = pd.np.where(df.a < 2, 0, pd.np.where((df.a >= 2) & (df.a < 4), 1, 2))
df
#   a   b   res
#0  1   3   0
#1  2   6   1
#2  3   4   1
#3  4   2   2
#4  5   7   2
#5  6   7   2
#6  7   1   2

答案 2 :(得分:3)

<强> searchsorted
应该给你更高效的结果。与pd.cut类似,您需要指定断点。

pandas
pd.Series.searchsorted

df.assign(res=pd.Series([2, 4]).searchsorted(df.a, side='right'))

   a  b  res
0  1  3    0
1  2  6    1
2  3  4    1
3  4  2    2
4  5  7    2
5  6  7    2
6  7  1    2

numpy
ndarray.searchsorted

df.assign(res=np.array([2, 4]).searchsorted(df.a.values, side='right'))

   a  b  res
0  1  3    0
1  2  6    1
2  3  4    1
3  4  2    2
4  5  7    2
5  6  7    2
6  7  1    2

计时

%timeit df.assign(res=pd.Series([2, 4]).searchsorted(df.a, side='right'))
%timeit df.assign(res=np.array([2, 4]).searchsorted(df.a.values, side='right'))
%timeit df.assign(res=pd.np.where(df.a < 2, 0, pd.np.where((df.a >= 2) & (df.a < 4), 1, 2)))
%timeit df.assign(res=pd.cut(df.a, [-np.inf,2,4,np.inf], labels=[0,1,2], right=False))

1000 loops, best of 3: 443 µs per loop
1000 loops, best of 3: 337 µs per loop
1000 loops, best of 3: 1.06 ms per loop
1000 loops, best of 3: 530 µs per loop