通过2个不同长度和索引操作的数组运行for循环

时间:2017-07-02 22:55:31

标签: python arrays numpy for-loop indexing

我需要在2个不同长度的数组中运行for循环。一个数组是8760乘1,另一个是10乘1.如果短数组中的值等于long数组中的值的索引,我不想改变任何东西。如果long数组中的值的索引不等于short数组中的值,我想将其设置为等于零。我知道我的代码是错的,但这是一个开始。我无法附加较长的数组,但现在它可能是随机值。

I = np.array([4993,4994,4995,5016,5017,5018,5019,5042,5043,5066])

import numpy as np

A = np.loadtxt('A.txt')
I = np.loadtxt('I.txt')

for i in A:
    for j in I:
        if A[j] != I[j]:
            i = 0

2 个答案:

答案 0 :(得分:1)

主要原则

当你需要for循环遍历数组的索引时,使用“计数”循环 - 循环遍历一组整数。使用for index in range(len(列表)

您的具体问题

根据您的I,我认为您要求将A的所有值设置为0(例如,分配A[5] = 0),例如A[4993]对于I中的索引,将保持不变,等等。

good_elements_indices = I
all_elements = A
for all_elements_index in range(len(all_elements)):
    if all_elements_index not in good_elements_index:
        A[all_elements_index] = 0

其他评论

  • Python样式使用小写的变量名称,单词之间有下划线,没有缩写。因此,我重命名为IA。请参阅PEP 8: Python Style Guide
  • in运算符是核心Python。由于您已导入numpygood_elements_index又名I已经是numpy.array个对象,因此建议使用numpy.isin功能更快但更不通用mrcl
  • 你的问题谈到“在2个数组中运行for循环”。这表明不是一个for循环,而是嵌套的两个for循环,正如您的问题代码所示。 in运算符实际上在列表测试中迭代为for循环,以便在集合中存在。

答案 1 :(得分:1)

numpy “没有循环”的一般想法我想展示它是怎么回事 是否可以执行OP提出的任务(显式) 循环。

我们将使用numpy的扩展寻址功能 让它以速度处理数据操作细节。

举一个例子,我需要一些data和一个列表,或者 这里命名为persisting的向量,与那些对应的索引 请求在修改后的data数组中保留的值 我们程序的结束。

import numpy as np
data = np.arange(10)
persisting = [4,8,1,0]

鉴于这些预备知识,我们可以计算出一个held数组 我们要保留的所有data元素indexing the data array using the persisting array

held = data[persisting]

data数组可以使用全速填充零 数组方法 .fill() 最终保存在held中的元素可以恢复到其中 原始地方,再次使用扩展寻址,这次是在左边 任务。

data.fill(0)
data[persisting] = held
print(data) #>>> [0 1 0 0 4 0 0 0 8 0]

上面描述的程序可能比其他程序更快或更快 取决于您正在操作的数组的len() 分别是多少,而不是 保持以前的价值。如果你的生产问题是你的 考虑对您所采用的各种方法进行基准测试 建议。

基准

我已经按照接受的答案和我的方法提出了方法。以下是记录我的程序的IPython会话的记录。

打印的结果是数据数组的长度,索引数组的长度,使用的时间(以秒为单位)(平均超过7次重复),以执行两个函数中的每一个。

In [38]: import numpy as np

In [39]: def accepted(A, I):
    ...:     good_elements_indices = I
    ...:     all_elements = A
    ...:     for all_elements_index in range(len(all_elements)):
    ...:         if all_elements_index not in good_elements_indices:
    ...:             A[all_elements_index] = 0.0
    ...:             

In [40]: def alternate(a, i):
    ...:     held = a[i]
    ...:     a.fill(0.0)
    ...:     a[i] = held
    ...:     

In [41]: for length in (100, 10000, 1000000):
    ...:     a = np.arange(length)
    ...:     for remain in (10, 100, 10000, length//2):
    ...:         if remain < length:
    ...:             i = np.random.choice(length, remain)
    ...:             acc_t = %timeit -q -o  accepted(a, i)
    ...:             alt_t = %timeit -q -o alternate(a, i)
    ...:             print('%10d, %10d: %e, %e;'%(
    ...:                    length, remain, acc_t.average, alt_t.average))
    ...:                    
       100,         10: 1.506336e-04, 1.126085e-06;
       100,         50: 1.663167e-04, 1.385859e-06;
     10000,         10: 1.539412e-02, 5.308621e-06;
     10000,        100: 2.198021e-02, 6.056105e-06;
     10000,       5000: 2.995333e-01, 3.775863e-05;
   1000000,         10: 1.524685e+00, 1.596268e-03;
   1000000,        100: 2.187460e+00, 1.599069e-03;
   1000000,      10000: 7.067548e+01, 1.770094e-03;
^C---------------------------------------------------------------------------
KeyboardInterrupt                         Traceback (most recent call last)

请注意,我必须中断计时过程,因为%timeit计算了七次重复的平均值,这意味着最后一行需要超过8'才能完成......

我必须说接受的答案可以很容易地加速,但我认为必须处理循环和测试它会慢一些。