我有一列数字,其中包含数字和NaN。我想添加一列标签,用1和0来标识我们有编号的“区域”:该区域包括相邻的(上方和下方)行。
结果应该如下所示:
Number Label
Nan 0
Nan 1
4 1
Nan 1
Nan 0
Nan 0
Nan 1
8.9 1
Nan 1
Nan 0
Nan 0
Nan 1
47 1
我想出了以下解决方案。但它很难看,如果我想标记更多相邻的单元格(在下面的+2以上),它就不会缩放。
import numpy as np
import pandas as pd
pd.set_option('display.max_rows', 100)
# Generating our DataFrame and ensuring there are some NaN
df = pd.DataFrame(np.random.randn(100), columns=['number'])
df.loc[df.number<1] = np.nan
# diffusing the values on adjacent cells and summing
df['label'] = df.number.fillna(0)
+ df.number.shift(1).fillna(0)
+ df.number.shift(-1).fillna(0)
# Replace values by 1
df.loc[df.label>0, 'label'] = 1
print(df)
有人能帮我找到一个更优雅的解决方案吗?也许用一个很好的Df.应用程序,我用起来有很多困难?
2条答案
按热度按时间3z6pesqy1#
基于移位法
(剧透提醒:这是我的第一个答案,但不是我最好的。这不是最快的。有关更快的解决方案,请参阅开机自检结束)
只要您的条件仍然是“前一行、当前行或下一行的数字”(我的意思是,如果您不想将其扩展到“k个前一行或k个下一行”),
shift
方法似乎是最快的方法。尽管如此,我对fillna
的想法并不确定。我会用一种更直接的方法
滑动窗口-view
(其他扰乱:我认为这种方法只适用于一般情况,而不适用于3行大窗口(当前为+1之前为+1之后)的特定情况)。但事实上,即使是在这种情况下,它也更快)
使用变量窗口,您可以使用
np.lib.stride_tricks.sliding_window_view
快速查看相邻值请注意,顾名思义,
sliding_window_view
是一个视图。而不是数据的副本。因此,即使您有100,000行并且PADDING_VALUE
是10000,它也不会用100亿个2D数组填满您的内存。这只是检查单行中相邻值的一种方便方法。我最近在另一个答案中使用了它,我对此做了更多的解释。
这4种方法的结果(到目前为止):你的,Steinn Hauser Magnusson的,和我的2
方法|计时(Ms)
你的|1.58
My Shift-One-liner|1.30
Steinn卷积|0.58
滑动窗口|0.28
所以,我必须承认,我没有想到卷积和我的第二种方法会比简单的“3行”情况下的简单一行程序更快。但是这个滑动窗口视图函数非常快(因为,同样,它只是一个视图),即使在这种情况下,它也是最快的。它在两个标准上都是赢家:它是最快的,但你可以选择窗口大小。
iqjalb3h2#
我建议对此使用卷积运算。当您想要“屏蔽”某个特定空间上的数组时,它真的很棒。在本例中,您希望屏蔽数组[...,1,1,1,...]在每个
label == 1
的顶部。以下是我的做法:请注意,当您应用卷积时,一些值加起来可能大于1(如果填充特别大,或者“1元素”非常接近)。出于这个原因,我将所有大于1的值都设置为等于1,但是您可能有另一个用例。希望这个能帮上忙!