熊猫切片更快

时间:2018-11-02 09:19:57

标签: pandas dataframe apply

我目前有一个函数和一个循环。目的是遍历数据帧中的每一列,如果索引值小于functino定义的值,则将其值设置为0(如果不保留为当前值)。

它正在工作,但要花很多时间才能运行。谁能看到更好的方法?我觉得我应该使用loc或iloc,但不确定如何应用

df = pd.DataFrame(np.random.randint(0, 20, [5, 3]), columns=['A', 'B', 'C'])

   A   B   C
0   6  19  14
1  10   7   6
2  18  10  10
3   3   7   2
4   1  11   5

def split(variable_name,sDate,eDate,df):
    if eDate =='end':
        lv=df.index[-1]
        y=np.logical_and(df.index>=sDate, df.index<=lv)
        df['newvar']=y.astype(int)*df[variable_name]
    else:
        lv=eDate
        y=np.logical_and(df.index>=sDate, df.index<=eDate)
        df['newvar']=y.astype(int)*df[variable_name]
    return df

for i in df.columns:
   split(i,1,'end',df)

输出

   A   B   C
0   0  0  0
1  0   0   0
2  18  10  10
3   3   7   2
4   1  11   5 

2 个答案:

答案 0 :(得分:1)

我相信您需要按列进行比较,然后按mul进行过滤:

np.random.seed(123)
df = pd.DataFrame(np.random.randint(0, 20, [5, 3]), columns=['A', 'B', 'C'])
print (df)
    A   B   C
0  13   2   2
1   6  17  19
2  10   1   0
3  17  15   9
4   0  14   0

def split(cols,sDate,eDate,df):

    #thanks jpp
    lv = df.index[-1] if eDate == 'end' else eDate

    y=np.logical_and(df.index>=sDate, df.index<=lv).astype(int)
    #alternative
    #y= (df.index>=sDate & df.index<=lv).astype(int)
    df[cols] = df[cols].mul(y, axis=0)
    #numpy alternative for multiple 
    #df[cols] = df[cols].values * y[:, None]
    return df


df1 = split(df.columns,1,'end',df)
print (df1)
    A   B   C
0   0   0   0
1   6  17  19
2  10   1   0
3  17  15   9
4   0  14   0

df1 = split(['A','B'],1,'end',df)
print (df1)
    A   B   C
0   0   0   2
1   6  17  19
2  10   1   0
3  17  15   9
4   0  14   0

答案 1 :(得分:1)

要获得您提到的确切输出,只需编写:

df.iloc[:2] = 0

这会将索引值<2的任何行设置为零。您当然可以指定任何范围,而无需循环,利用快速的Pandas向量化操作。