np.where: “ValueError: operands could not be broadcast together with shapes (38658637,) (9456,)”

我有两个形状不同的数据框:

  1. df_rts_1 #形状: (38658637, 7)
  2. df_crsh_rts #形状: (9456, 6)

我尝试使用 np.where 来更新一个列值 (df_rts_1['crash']),根据以下条件将其设置为 1

  1. df_rts_1['tmc_code']= df_crsh_rts['tmc']
  2. df_rts_1['measurement_tstamp'] 在 df_crsh_rts['Start_time'] 和 df_crsh_rts['Closed_time'] 之间

我的代码:

df_rts_1['crash'] = np.where((df_rts_1['tmc_code'].values == df_crsh_rts['tmc'].values) & ((df_rts_1['measurement_tstamp'].values > df_crsh_rts['Start_time'].values) & (df_rts_1['measurement_tstamp'].values > df_crsh_rts['Closed_time'].values)), 1, df_rts_1['crash'])

我遇到了标题中的错误。我对Python/数据科学非常新手。


回答:

假设你的两个数据框包含以下内容:

  1. df_rts_1

        tmc_code  measurement_tstamp  crash 0         1 2020-01-03 10:05:00      0 1         1 2020-01-03 11:00:00      0 2         1 2020-01-03 12:10:00      0 3         2 2020-01-03 10:10:00      0 4         3 2020-01-03 10:05:00      0
  2. df_crsh_rts

        tmc          Start_time         Closed_time 0    1 2020-01-03 10:00:00 2020-01-03 11:00:00 1    2 2020-01-03 14:00:00 2020-01-03 15:00:00 2    4 2020-01-03 16:00:00 2020-01-03 18:00:00

为了便于评估“在…之间”的条件,让我们创建以下IntervalIndex

interv = pd.IntervalIndex.from_arrays(df_crsh_rts.Start_time,    df_crsh_rts.Closed_time, closed='both')

现在,假设我们有来自 df_rts_1 的当前,让我们构建你的条件:

  • “在…之间”的条件可以表示为 interv.contains(row.measurement_tstamp)
  • tmc / tmc_code 值的相等性可以表示为df_crsh_rts.tmc.eq(row.tmc_code)

为了检查它们的效果,将 df_rts_1 的第一行保存为row变量:

row = df_rts_1.iloc[0]

然后执行这两个条件。

第一个条件生成一个Numpy数组,类型为bool

array([ True, False, False])

而第二个条件生成一个Series(也是bool类型):

0     True1    False2    FalseName: tmc, dtype: bool

因此,为了构建最终的(单个)bool值——即这一行是否应该更新其crash列,条件是:

(interv.contains(row.measurement_tstamp) & df_crsh_rts.tmc.eq(row.tmc_code)).any()

即两个上述条件的逻辑AND操作以及any()——是否任何一个连接元素为True

与你的代码相比,最后的变化是:

  • 不使用where,而是使用iloc[…],其中第一个参数(行选择器)是上述复合条件,为 df_rts_1 的每一行计算(使用列表解析)——哪些行需要更新。
  • 第二个参数只是crash——要更新的列名。
  • 在指定的单元格中保存1

执行此操作的代码如下:

df_rts_1.loc[[ (interv.contains(row.measurement_tstamp) &    df_crsh_rts.tmc.eq(row.tmc_code)).any()    for row in df_rts_1.itertuples()], 'crash'] = 1

对于我的样本数据,结果是:

   tmc_code  measurement_tstamp  crash0         1 2020-01-03 10:05:00      11         1 2020-01-03 11:00:00      12         1 2020-01-03 12:10:00      03         2 2020-01-03 10:10:00      04         3 2020-01-03 10:05:00      0

根据评论中的问题进行编辑

Q1。我们是否使用来自两个条件的索引来访问和更新 df_rts_1 数据框?

实际上不是。请注意:

[ (interv.contains(row.measurement_tstamp) &    df_crsh_rts.tmc.eq(row.tmc_code)).any() for row in df_rts_1.itertuples() ]

生成一个bool列表,它甚至不包含原始索引。然后在.loc[…]中使用它,所以这是布尔索引的情况。这个列表的连续True / False元素与 df_rts_1 的连续行相关,并表示特定的行是否应被选择。

Q2Q3any()在这里做什么?any()帮助我们实现什么?

看一下初始行的例子:

  • 第一个条件(单独)表示当前中的measurement_tstamp是否在 df_crsh_rts 的连续行中的两个日期之间,
  • 第二个条件(单独)表示当前是否在 df_crsh_rts 的连续行中有匹配的tmc

我们要求这两个条件必须在 df_crsh_rts同一行中满足,因此使用&将它们连接起来。

但是请注意:

  • condition_1 & condition_2 生成一个bool类型的Series——是否连续行满足这两个部分条件:

    0    True1    False2    FalseName: tmc, dtype: bool
  • 但我们不需要任何bool类型的Series。我们需要一个单一bool,表示上述结果是否包含至少一个True值。

而正是这个转换(从bool Series到一个单一bool)由any()执行。

编辑 2

由于你的数据量巨大,我提出了另一个可能更快的解决方案。思路是:

  • tmc_codedf_rts_1进行分组,
  • 仅检查当前tmc的区间内的between条件,
  • 为了更快地选择正确的区间,使用一个辅助的Series,其中区间按tmc索引(按索引搜索更快)。

为此,定义以下函数,应用于每个组:

def newCrash(grp):    # 当前 tmc_code 的区间    wrk = intrv[intrv.index == grp.iloc[0,0]]    if wrk.empty:        return grp.crash  # 未找到 - 不更改    wrkInd = pd.IntervalIndex(wrk)    return grp.crash.mask([ wrkInd.contains(ts).any()        for ts in grp.measurement_tstamp ], 1)

然后创建辅助的Series

intrv = pd.Series(pd.IntervalIndex.from_arrays(df_crsh_rts.Start_time,    df_crsh_rts.Closed_time, closed='both'), index=df_crsh_rts.tmc)

最后运行更新crash列:

df_rts_1.crash = df_rts_1.groupby('tmc_code', sort=False).\    apply(newCrash).reset_index(level=0, drop=True)

对于你(非常小)的样本数据,这个解决方案运行得较慢。

但当我将df_rts_1的大小增加到40行时,这个解决方案运行得稍快一些。

如果你进一步增加df_rts_1的大小,速度差异应该会更大(有利于第二个解决方案)。

df_rts_1的样本上(例如100,000行)测试两种解决方案(原始的和这个),并写下两种解决方案的执行时间。

Related Posts

使用LSTM在Python中预测未来值

这段代码可以预测指定股票的当前日期之前的值,但不能预测…

如何在gensim的word2vec模型中查找双词组的相似性

我有一个word2vec模型,假设我使用的是googl…

dask_xgboost.predict 可以工作但无法显示 – 数据必须是一维的

我试图使用 XGBoost 创建模型。 看起来我成功地…

ML Tuning – Cross Validation in Spark

我在https://spark.apache.org/…

如何在React JS中使用fetch从REST API获取预测

我正在开发一个应用程序,其中Flask REST AP…

如何分析ML.NET中多类分类预测得分数组?

我在ML.NET中创建了一个多类分类项目。该项目可以对…

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注