【问题标题】:pandas dataframe fails to assign value to slice subset熊猫数据框无法为切片子集赋值
【发布时间】:2019-01-03 03:30:57
【问题描述】:

我正在尝试更改切片中除第一个之外的所有值,但它不起作用...我做错了什么?

print(test)
test.loc[(test.col_1==-5)&(test.index>'2018-07-17 13:00:00')&(test.index<'2018-07-17 14:00:00'),['col_1']][1:]=-1
print(test)

提供以下输出

17/07/2018 13:51:00 -5
17/07/2018 13:52:00 -1
17/07/2018 13:53:00 -5
17/07/2018 13:54:00 -5
17/07/2018 13:55:00 -5
17/07/2018 13:56:00 -5
17/07/2018 13:57:00 -5
17/07/2018 13:58:00 -5
17/07/2018 13:59:00 -5

17/07/2018 13:51:00 -5
17/07/2018 13:52:00 -1
17/07/2018 13:53:00 -5
17/07/2018 13:54:00 -5
17/07/2018 13:55:00 -5
17/07/2018 13:56:00 -5
17/07/2018 13:57:00 -5
17/07/2018 13:58:00 -5
17/07/2018 13:59:00 -5

而我期望第二个输出是

17/07/2018 13:51:00 -5
17/07/2018 13:52:00 -1
17/07/2018 13:53:00 -1
17/07/2018 13:54:00 -1
17/07/2018 13:55:00 -1
17/07/2018 13:56:00 -1
17/07/2018 13:57:00 -1
17/07/2018 13:58:00 -1
17/07/2018 13:59:00 -1

【问题讨论】:

  • 可以加minimal, complete, and verifiable example吗?因为看起来两个 DataFrame 都是一样的。
  • @jezrael:我使用了一张图片来避免编写一些 html ......但还可以......为了争论,虽然这不是一些代码而是输出结果。
  • @jezrael:如果您首先正确阅读了该示例,则该示例很明确...显然您没有,并且对问题投了反对票,因为您没有花费超过 1 分钟的时间来理解它好可怜……
  • 谢谢,有时实际情况会有所不同 ;) 所以你需要过滤DataFrame 的第一行还是需要过滤掉布尔掩码的第一个 True 值?

标签: python python-3.x pandas numpy indexing


【解决方案1】:

选择加入布尔索引(过滤)存在问题,一种可能的解决方案是添加新条件:

test.index = pd.to_datetime(test.index)
mask = (test.col_1==-5)&(test.index>'2018-07-17 13:00:00')&(test.index<'2018-07-17 14:00:00')

m1 = np.arange(len(test)) > 1
test.loc[mask & m1, 'col_1']=-1

print (test)
                     col_1
2018-07-17 13:51:00     -5
2018-07-17 13:52:00     -1
2018-07-17 13:53:00     -1
2018-07-17 13:54:00     -1
2018-07-17 13:55:00     -1
2018-07-17 13:56:00     -1
2018-07-17 13:57:00     -1
2018-07-17 13:58:00     -1
2018-07-17 13:59:00     -1

【讨论】:

  • 问题不在于如何以不同的方式做到这一点,而是为什么以目前的形式它不起作用。基本上问题比这复杂得多,所以我将我的问题简化为这一点。使用 2 步掩码方法不适合我所面临的整体和更复杂的画面
【解决方案2】:

您可以使用numpy.where 并使用索引[1:] 来排除第一次条件为True。这是一个最小的例子:

df = pd.DataFrame([[1, -5], [2, -5], [3, -1], [4, -5], [5, -5], [6, -1]],
                  columns=['col1', 'col2'])

df.iloc[np.where(df['col1'].between(2, 5))[0][1:], 1] = -1

print(df)

   col1  col2
0     1    -5
1     2    -5
2     3    -1
3     4    -1
4     5    -1
5     6    -1

【讨论】:

  • 谢谢 jpp - 我认为这确实是我做错了,即:我应该考虑使用 iloc 和 np.where !!!
  • @RogerLePatissier,是的,有时探索避免双重面具的方法很有用。通常可以通过矢量化方式实现。
猜你喜欢
  • 1970-01-01
  • 2021-12-04
  • 2021-10-28
  • 2015-08-11
  • 1970-01-01
  • 2016-03-28
  • 2017-02-22
  • 2021-02-27
  • 1970-01-01
相关资源
最近更新 更多