Python 将fillna与条件熊猫一起使用

Python 将fillna与条件熊猫一起使用,python,pandas,Python,Pandas,我有以下数据框,我想应用如下: 数据: 我只想在值为8时应用ffill,该值应产生所需的输出(注意,它仅在填充值为8时填充): 这方面的任何帮助都会很好 因此,如果只有前面的值是8,则基本上您希望用8填充nan: df[df.shift().eq(8) & df.isnull()] = 8 我错过了一部分。尝试这个简单的循环: for col in df.columns: filters = df[col].eq(8) | df[col].isnull() df.loc

我有以下数据框,我想应用如下:

数据:

我只想在值为8时应用
ffill
,该值应产生所需的输出(注意,它仅在填充值为8时填充):


这方面的任何帮助都会很好

因此,如果只有前面的值是
8
,则基本上您希望用
8
填充
nan

df[df.shift().eq(8) & df.isnull()] = 8
我错过了一部分。尝试这个简单的循环:

for col in df.columns:
    filters = df[col].eq(8) | df[col].isnull()
    df.loc[filters,col] = df.loc[filters,col].ffill()

编辑2:今天早上匆忙离开,没有仔细检查。这里有一个解决方案:

for col in df.columns:
    # mark all na blocks with their previous row
    filters = (~df[col].isna()).cumsum()

    # record those nan blocks with starting 8
    eq8 = filters[df[col].eq(8)]

    # filter these block
    filters = filters.isin(eq8)

    # fill these block with 8
    df.loc[filters, col] = 8

因此,基本上,如果只有前面的值是
8
,您希望用
8
填充
nan

df[df.shift().eq(8) & df.isnull()] = 8
我错过了一部分。尝试这个简单的循环:

for col in df.columns:
    filters = df[col].eq(8) | df[col].isnull()
    df.loc[filters,col] = df.loc[filters,col].ffill()

编辑2:今天早上匆忙离开,没有仔细检查。这里有一个解决方案:

for col in df.columns:
    # mark all na blocks with their previous row
    filters = (~df[col].isna()).cumsum()

    # record those nan blocks with starting 8
    eq8 = filters[df[col].eq(8)]

    # filter these block
    filters = filters.isin(eq8)

    # fill these block with 8
    df.loc[filters, col] = 8

这远远不够理想,而且有一个有趣的问题,为什么函数
cond_fill
只在一列的数据帧上工作。添加第二个,则不会应用它

import pandas as pd
import numpy as np
print(pd.__version__)

df = pd.DataFrame(np.random.choice([1,np.nan,8], size=(10,1)), columns=['a'])
#df = pd.DataFrame(np.random.choice([1,np.nan,8], size=(10,2)), columns=['a', 'b'])

cols = df.columns

def cond_fill(s):
    fill = False
    for i,x in s.iteritems():
        # set a '9' so we can see the change
        if pd.isnull(x) and fill: s.loc[i] = 9
        else: fill = False

        if x == 8: fill = True

    return x

df.apply(cond_fill)

print(df)

产生

0.24.2
     a
0  NaN
1  1.0
2  NaN
3  NaN
4  8.0
5  9.0
6  1.0
7  NaN
8  8.0
9  9.0


这远远不够理想,而且有一个有趣的问题,为什么函数
cond_fill
只在一列的数据帧上工作。添加第二个,则不会应用它

import pandas as pd
import numpy as np
print(pd.__version__)

df = pd.DataFrame(np.random.choice([1,np.nan,8], size=(10,1)), columns=['a'])
#df = pd.DataFrame(np.random.choice([1,np.nan,8], size=(10,2)), columns=['a', 'b'])

cols = df.columns

def cond_fill(s):
    fill = False
    for i,x in s.iteritems():
        # set a '9' so we can see the change
        if pd.isnull(x) and fill: s.loc[i] = 9
        else: fill = False

        if x == 8: fill = True

    return x

df.apply(cond_fill)

print(df)

产生

0.24.2
     a
0  NaN
1  1.0
2  NaN
3  NaN
4  8.0
5  9.0
6  1.0
7  NaN
8  8.0
9  9.0


这是一种完全不同的方法,适用于n列,速度很快

import pandas as pd
import numpy as np
print(pd.__version__)

df = pd.DataFrame(np.random.choice([1,np.nan,8], size=(10,2)), columns=['a', 'b'])

print(df)

for col in df.columns:
    new_col_1 = "{}_1".format(col)
    df[new_col_1] = df[col].fillna(8)
    new_col_2 = "{}_2".format(col)
    df[new_col_2] = df[col].ffill()

    df[col] = df[col].ffill()
    df[col][df[new_col_1] != df[new_col_2]] = np.nan
    df.drop([new_col_1, new_col_2], axis=1, inplace=True)

print(df)

将产生如下结果:

0.24.2
     a    b
0  8.0  1.0
1  1.0  NaN
2  8.0  8.0
3  1.0  NaN
4  NaN  8.0
5  8.0  NaN
6  1.0  8.0
7  NaN  8.0
8  8.0  1.0
9  NaN  8.0
     a    b
0  8.0  1.0
1  1.0  NaN
2  8.0  8.0
3  1.0  8.0
4  NaN  8.0
5  8.0  8.0
6  1.0  8.0
7  NaN  8.0
8  8.0  1.0
9  8.0  8.0


这是一种完全不同的方法,适用于n列,速度很快

import pandas as pd
import numpy as np
print(pd.__version__)

df = pd.DataFrame(np.random.choice([1,np.nan,8], size=(10,2)), columns=['a', 'b'])

print(df)

for col in df.columns:
    new_col_1 = "{}_1".format(col)
    df[new_col_1] = df[col].fillna(8)
    new_col_2 = "{}_2".format(col)
    df[new_col_2] = df[col].ffill()

    df[col] = df[col].ffill()
    df[col][df[new_col_1] != df[new_col_2]] = np.nan
    df.drop([new_col_1, new_col_2], axis=1, inplace=True)

print(df)

将产生如下结果:

0.24.2
     a    b
0  8.0  1.0
1  1.0  NaN
2  8.0  8.0
3  1.0  NaN
4  NaN  8.0
5  8.0  NaN
6  1.0  8.0
7  NaN  8.0
8  8.0  1.0
9  NaN  8.0
     a    b
0  8.0  1.0
1  1.0  NaN
2  8.0  8.0
3  1.0  8.0
4  NaN  8.0
5  8.0  8.0
6  1.0  8.0
7  NaN  8.0
8  8.0  1.0
9  8.0  8.0



我不确定你提供的字典是否给出了你期望的数据帧。您的索引是否为cj8e134xu02pixvky4r70o0se和
A_cj8t63fsb04ga5bm4ongrlx6h
。所以只有两行9列?或者有2列9行吗?2行9列
df.loc['A_cj8e134xu02pixvky4r70o0se']=df.loc['A_cj8e134xu02pixvky4r70o0se'].fillna(method='ffill')
?@Erfan这将填充所有值,我只希望在单元格中的值为8的情况下填充,否则,保留为NAI我不确定您提供的字典是否提供了您期望的数据帧。您的索引是否为cj8e134xu02pixvky4r70o0se和
A_cj8t63fsb04ga5bm4ongrlx6h
。所以只有两行9列?或者你有2列9行吗?2行9列
df.loc['A_cj8e134xu02pixvky4r70o0se']=df.loc['A_cj8e134xu02pixvky4r70o0se'].fillna(method='ffill')
?@Erfan这将填充所有值,我只希望在单元格中的值为8的情况下填充,否则,保留为anknaths,这将只填充一次,我想把它填到下一个有效的value@YehoshaphatSchellekens说得好。有关快速修复,请参阅更新。看起来像是
nabs
NaN
anywhere@RichAndrews它确实到处都选nan,但由于
ffill
良好的技术,它只在8之后填充nan,但似乎也在8之后填充。调用它几次,它应该是可见的
df=pd.DataFrame(np.random.choice([np.nan,1,8],size=(10,2)),columns=['a','b'])df[df.shift().eq(8)&df.isnull()]=8,用于df中的col。columns:filters=df[col]。eq(8)| df[col]。isnull()df[filters,col]=df.loc[filters,col]。ffill()
谢谢,这只会填充一次,我想把它填到下一个有效的value@YehoshaphatSchellekens说得好。有关快速修复,请参阅更新。看起来像是
nabs
NaN
anywhere@RichAndrews它确实到处都选nan,但由于
ffill
良好的技术,它只在8之后填充nan,但似乎也在8之后填充。调用它几次,它应该是可见的
df=pd.DataFrame(np.random.choice([np.nan,1,8],size=(10,2)),columns=['a','b'])df[df.shift().eq(8)&df.isnull()]=8表示df中的col。columns:filters=df[col]。eq(8)| df[col]。isnull()df[filters,col]=df.loc[filters,col]=dfill()
谢谢,我来看看!前面的答案似乎不起作用,不确定为什么它不能解决你的问题,因为它只能做一列。但是为什么apply()在不止一个专栏中失败对我来说是一个完全的谜,任何洞察都是值得赞赏的。谢谢,我来看看!前面的答案似乎不起作用,不确定为什么它不能解决你的问题,因为它只能做一列。但是为什么apply()在不止一个专栏中失败,对我来说是一个完全的谜,任何洞察都是值得赞赏的。