pandas查找非空值的起始点和结束点

5
我想找到一列的起始和结束点,并将它们标记如下:
value flag
NaN NaN
NaN NaN
1 开始
2 NaN
1 NaN
3 NaN
2 结束
NaN NaN
1 开始
2 结束
3个回答

5

使用shift生成这些条件,并使用loc进行赋值:

start = df.value.notnull() & df.value.shift().isnull()
stop = df.value.notnull() & df.value.shift(-1).isnull()

df.loc[start, 'flag'] = 'start'
df.loc[stop, 'flag'] = 'stop'

#    value   flag
# 0    NaN    NaN
# 1    NaN    NaN
# 2    1.0  start
# 3    2.0    NaN
# 4    1.0    NaN
# 5    3.0    NaN
# 6    2.0   stop
# 7    NaN    NaN
# 8    1.0  start
# 9    2.0   stop

或者可以使用mask进行赋值:

df['flag'] = df['flag'].mask(start, 'start')
df['flag'] = df['flag'].mask(stop, 'stop')

你好,你能推荐一种方法,只有在非空值的长度超过一定长度时才进行标记吗?例如,需要有10个连续数字才能标记开始和结束。我可以使用多个移位来实现,但这会使它变得相当冗长和混乱!谢谢 - kswizzle101_

1

在这里,我遍历了行,并使用一个标志来指示我们是否正在开始。

start_flag = 0
for index, row in df.iterrows():
  if row['val'].isnull():
    df.loc[index, 'flag'] = "NaN"
    start_flag = 0
  else:
    if start_flag == 0:
      df.loc[index, 'flag'] = "start"
      start_flag = 1
    else:
      if (index < df.shape[0]-1 and df.loc[index+1, 'val'].isnull()) or index == df.shape[0]-1:
         df.loc[index, 'flag'] = "stop"

1
除非没有其他选择,请不要使用迭代。遍历所有行是一个坏主意,而且代价高、速度慢。 - Joe Ferndz

1

以下是您需要的内容:

# Auxiliar columns to detect start and end
df['Past'] = df['Value'].shift(-1)
df['Future'] = df['Value'].shift(1)

# Auxiliar function to complete new column
def Find_start_stop_Null(row):
    flag = np.nan
    if ((not pd.isnull(row['Value'])) and (pd.isnull(row['Future']))):
        flag = 'start'
    elif ((not pd.isnull(row['Value'])) and (pd.isnull(row['Past']))):
        flag = 'stop'
    return flag

df['flag'] = df.apply(lambda row: Find_start_stop_Null(row), axis=1)
# Drop unnecessary columns
df = df.drop('Past', axis=1)
df = df.drop('Future', axis=1)

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接