14

我的 R 编程头连接到使用负切片索引来排除元素。

举个例子:

my_list = [0,1,2,3,4,5,6,7,8,9]
my_neg_slice = [-2, -8, 0, -5]

会回来

[1 3 4 6 7 9]

即返回所有不在 (0, 2, 5, 8) 中的索引。

这更像是一个满足我好奇心的问题,因为 Pythonic 负索引对我来说非常新颖(这不是对 Python 实现的批评,因为我非常喜欢它)。有人在 Python 中实现了 R_Style_Negative_Indexing 吗?我对 Python 很陌生,所以这种类型的索引可能已经存在?也许有人创建了自定义扩展(抱歉,如果这不是正确的术语)来扩展适当的库?

显然,这对于字符串来说是非常棘手的,但我希望人们可以通过排除一组已知的稀疏元素来看到想要切片成对象(List、Dict、DataFrame、...)的概念?

我在 Python 中执行负 R 样式索引的尼安德特人方式:

import numpy as np

my_list = [0,1,2,3,4,5,6,7,8,9]
my_neg_slice = [-2, -8, 0, -5]

# Convert my_list to a numpy array as it's much easier to work with
step0 = np.array(my_list)

# Same for the negative_slices
step1 = np.array(my_neg_slice)

# Identify the indexes that are negative (assume 0 implies exclude)
step2 = step1 <= 0

# For the negative indexes, flip the sign so they are positive
step3 = -step1[step2]

# Generate the complete index for my_list
step4 = np.arange(len(my_list))

# Identify the indices required by exlucing my_neg_slice indices
step5 = np.setdiff1d(step4, step3)

# Make a cup of tea! Maybe time to rewire the brain and think like a snake!
step6 = step0[step5]

print(step6)
[1 3 4 6 7 9]

我没有要解决的特定问题,我只是想通过索引建立我对可能性的理解?提前谢谢了。伯蒂。

4

5 回答 5

6

很惊讶没有人提到drop熊猫中的方法:

In [8]: s
Out[8]: 
0    0
1    1
2    2
3    3
4    4
5    5
6    6
7    7
8    8
9    9
dtype: int64

In [9]: s.drop([2, 8, 0, 5])
Out[9]: 
1    1
3    3
4    4
6    6
7    7
9    9
dtype: int64
于 2013-08-16T19:11:39.717 回答
6

既然你已经标记了这个熊猫,让我们做my_list一个系列:

In [11]: my_list = pd.Series(my_list)

并且让我们实际上采用(更pythonic)“负索引”来使用正数,如果我们不想这样做,那么对这部分使用列表理解以达到相同的效果(或者如果它本身就是一个numpy数组或系列那么只需-my_neg_slice):

In [12]: my_neg_slice = [2, 8, 0, 5]

然后,由于索引my_list只是一个枚举(在这种情况下),我们可以减去:

In [13]: my_list.index - my_neg_slice
Out[13]: Int64Index([1, 3, 4, 6, 7, 9], dtype=int64)

并查看其余位置的那些元素:

In [14]: my_list.iloc[my_list.index - my_neg_slice]
Out[14]: 
1    1
3    3
4    4
6    6
7    7
9    9
dtype: int64
于 2013-08-14T22:16:06.243 回答
2

使用集:

>>> set([0,1,2,3,4,5,6,7,8,9]) - set([0,2,5,8])
set([1, 3, 4, 6, 7, 9])

(使用正值而不是负值)。

于 2013-08-14T22:03:35.487 回答
1

这使用了稍微不同的格式my_neg_slice,但以下是一种 Pythonic 方式,可以按照您描述的方式过滤可迭代对象:

>>> my_list = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
>>> my_neg_slice = set([2, 8, 0, 5])
>>> [x for i, x in enumerate(my_list) if i not in my_neg_slice]
[1, 3, 4, 6, 7, 9]
于 2013-08-14T22:07:08.127 回答
1

这是个有趣的问题 !我想我会尝试提供一个numpy版本。据我所知,它必须依赖于类似于您提供的流程,您将在其中建立数据中的索引列表,然后消除您不想要的索引。

mask = np.ones(len(my_list), dtype=bool)
for i in my_neg_slice:
    mask[i] = False
my_list[mask]

不过,这有点浪费,因为您的掩码数组中需要包含与my_list. @FJ 的答案很好,因为它保留了“不在”切片的稀疏性。

更新

刚刚发现一个numpy邮件列表帖子似乎确认您需要使用某种掩码来执行此操作:http: //mail.scipy.org/pipermail/numpy-discussion/2008-May/034021.html

于 2013-08-14T22:11:31.793 回答