- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我创建了一些示例代码来模仿我得到的代码:
import numpy as np
arr = np.random.random(100)
arr2 = np.linspace(0, 1, 20)
arr3 = np.zeros(20) # this is the array i want to store the result in
for index, num in enumerate(list(arr2)):
arr3[index] = np.mean(arr[np.abs(num - arr) < 0.2])
>>> arr3
array([0.10970893, 0.1132479 , 0.14687451, 0.17257954, 0.19401919,
0.23852137, 0.29151448, 0.35715096, 0.43273118, 0.45800796,
0.52940421, 0.60345354, 0.63969432, 0.67656363, 0.72921913,
0.78330793, 0.82693675, 0.83717402, 0.86651827, 0.89782569])
我的问题是这段代码运行在更大的数据上。我想知道是否有可能在不使用显式循环的情况下以矢量化的方式组合 numpy 或 pandas。我尝试了很多方法,但没有想到什么。
最佳答案
如果您要处理大型数组,我会推荐一种完全不同的方法。现在,您正在整个 arr
中搜索 arr2
中的每个元素。这显然是矫枉过正。相反,您可以对排序的 arr
进行操作,并简单地对从 np.searchsorted
获得的插入点求和。 .
如果可以的话,将 arr
排序到位:
arr.sort()
您知道间隔的宽度,因此找到边界值。我正在制作形状为 (20, 2)
的数组以更轻松地匹配边界:
bounds = arr2.reshape(-1, 1) + [-0.2, 0.2]
现在找到插入索引:
ind = np.searchsorted(arr, bounds)
ind
与 bounds
的形状相同。 ind[i, :]
是 arr
的开始(包括)和结束(不包括)索引,对应于 i
的第 arr2
。换句话说,对于任何给定的 i
,原始问题中的 arr3[i]
是 arr[ind[i, 0]:ind[i, 1] .mean()
。您可以直接将其用于非矢量化解决方案:
result = np.array([arr[slice(*i)].mean() for i in ind])
有几种方法可以向量化解决方案。无论哪种情况,您都需要每次运行中的元素数量:
n = np.diff(ind, axis=1).ravel()
一个容易出现舍入错误的快速而肮脏的解决方案使用 np.cumsum
和使用 ind
的奇特索引:
cumulative = np.r_[0, np.cumsum(arr)]
sums = np.diff(cumulative[ind], axis=1).ravel()
result = sums / n
更稳健的解决方案是使用 np.add.reduceat
仅提取您实际需要的总和:
arr = np.r_[arr, 0] # compensate for index past the end
sums = np.add.reduceat(arr, ind.ravel())[::2]
result = sums / n
您可以将两种方法的结果与问题中计算的 arr3
进行比较,以验证第二种方法是否明显更准确,即使是您的玩具示例也是如此。
时间
def original(arr, arr2, d):
arr3 = np.empty_like(arr2)
for index, num in enumerate(arr2):
arr3[index] = np.mean(arr[np.abs(num - arr) < d])
return arr3
def ananda(arr, arr2, d):
arr_tile = np.tile(arr, (len(arr2), 1))
arr_tile[np.abs(arr - arr2[:, None]) >= d] = np.nan
return np.nanmean(arr_tile, axis=1)
def mad_0(arr, arr2, d):
arr.sort()
ind = np.searchsorted(arr, arr2.reshape(-1, 1) + [-d, d])
return np.array([arr[slice(*i)].mean() for i in ind])
def mad_1(arr, arr2, d):
arr.sort()
ind = np.searchsorted(arr, arr2.reshape(-1, 1) + [-d, d])
n = np.diff(ind, axis=1).ravel()
sums = np.diff(np.r_[0, np.cumsum(arr)][ind], axis=1).ravel()
return sums / n
def mad_2(arr, arr2, d):
arr.sort()
ind = np.searchsorted(arr, arr2.reshape(-1, 1) + [-d, d])
n = np.diff(ind, axis=1).ravel()
arr = np.r_[arr, 0]
sums = np.add.reduceat(arr, ind.ravel())[::2]
return sums / n
输入(每次运行重置):
np.random.seed(42)
arr = np.random.rand(100)
arr2 = np.linspace(0, 1, 1000)
结果:
original: 25.5 ms ± 278 µs per loop (mean ± std. dev. of 7 runs, 10 loops each)
ananda: 2.66 ms ± 35.3 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)
mad_0: 14.5 ms ± 48.6 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)
mad_1: 211 µs ± 1.41 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)
mad_2: 242 µs ± 1.93 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)
对于具有 1k 个 bin 的 100 个元素,原始方法比使用 np.tile
慢约 10 倍。使用列表理解仅比原始方法好 2 倍。虽然 np.cumsum
方法似乎比 np.add.reduce
快一点,但它在数值上可能不太稳定。
使用我建议的方法的另一个好处是你可以任意改变arr2
,而arr
只需要排序一次。
关于python - numpy/pandas 向量化自定义 for 循环,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/65495249/
pandas.crosstab 和 Pandas 数据透视表似乎都提供了完全相同的功能。有什么不同吗? 最佳答案 pivot_table没有 normalize争论,不幸的是。 在 crosstab
我能找到的最接近的答案似乎太复杂:How I can create an interval column in pandas? 如果我有一个如下所示的 pandas 数据框: +-------+ |
这是我用来将某一行的一列值移动到同一行的另一列的当前代码: #Move 2014/15 column ValB to column ValA df.loc[(df.Survey_year == 201
我有一个以下格式的 Pandas 数据框: df = pd.DataFrame({'a' : [0,1,2,3,4,5,6], 'b' : [-0.5, 0.0, 1.0, 1.2, 1.4,
所以我有这两个数据框,我想得到一个新的数据框,它由两个数据框的行的克罗内克积组成。正确的做法是什么? 举个例子:数据框1 c1 c2 0 10 100 1 11 110 2 12
TL;DR:在 pandas 中,如何绘制条形图以使其 x 轴刻度标签看起来像折线图? 我制作了一个间隔均匀的时间序列(每天一个项目),并且可以像这样很好地绘制它: intensity[350:450
我有以下两个时间列,“Time1”和“Time2”。我必须计算 Pandas 中的“差异”列,即 (Time2-Time1): Time1 Time2
从这个 df 去的正确方法是什么: >>> df=pd.DataFrame({'a':['jeff','bob','jill'], 'b':['bob','jeff','mike']}) >>> df
我想按周从 Pandas 框架中的列中累积计算唯一值。例如,假设我有这样的数据: df = pd.DataFrame({'user_id':[1,1,1,2,2,2],'week':[1,1,2,1,
数据透视表的表示形式看起来不像我在寻找的东西,更具体地说,结果行的顺序。 我不知道如何以正确的方式进行更改。 df示例: test_df = pd.DataFrame({'name':['name_1
我有一个数据框,如下所示。 Category Actual Predicted 1 1 1 1 0
我有一个 df,如下所示。 df: ID open_date limit 1 2020-06-03 100 1 2020-06-23 500
我有一个 df ,其中包含与唯一值关联的各种字符串。对于这些唯一值,我想删除不等于单独列表的行,最后一行除外。 下面使用 Label 中的各种字符串值与 Item 相关联.所以对于每个唯一的 Item
考虑以下具有相同名称的列的数据框(显然,这确实发生了,目前我有一个像这样的数据集!:() >>> df = pd.DataFrame({"a":range(10,15),"b":range(5,10)
我在 Pandas 中有一个 DF,它看起来像: Letters Numbers A 1 A 3 A 2 A 1 B 1 B 2
如何减去两列之间的时间并将其转换为分钟 Date Time Ordered Time Delivered 0 1/11/19 9:25:00 am 10:58:00 am
我试图理解 pandas 中的下/上百分位数计算,但有点困惑。这是它的示例代码和输出。 test = pd.Series([7, 15, 36, 39, 40, 41]) test.describe(
我有一个多索引数据框,如下所示: TQ bought HT Detailed Instru
我需要从包含值“低”,“中”或“高”的数据框列创建直方图。当我尝试执行通常的df.column.hist()时,出现以下错误。 ex3.Severity.value_counts() Out[85]:
我试图根据另一列的长度对一列进行子串,但结果集是 NaN .我究竟做错了什么? import pandas as pd df = pd.DataFrame([['abcdefghi','xyz'],
我是一名优秀的程序员,十分优秀!