Python Dataframe.ItErrors()或Dataframe.itertuples()的替代方案?

Python Dataframe.ItErrors()或Dataframe.itertuples()的替代方案?,python,pandas,dataframe,vectorization,Python,Pandas,Dataframe,Vectorization,我对熊猫数据帧矢量化(通过熊猫矢量化本身或通过Numpy)的理解是将函数应用于数组,类似于.apply()(如果我错了,请纠正我)。假设我有以下数据帧: import pandas as pd df = pd.DataFrame({'color' : ['red','blue','yellow','orange','green', 'white','black','brown','orange-red','teal',

我对熊猫数据帧矢量化(通过熊猫矢量化本身或通过Numpy)的理解是将函数应用于数组,类似于.apply()(如果我错了,请纠正我)。假设我有以下数据帧:

import pandas as pd
df = pd.DataFrame({'color' : ['red','blue','yellow','orange','green',
                         'white','black','brown','orange-red','teal',
                         'beige','mauve','cyan','goldenrod','auburn',
                         'azure','celadon','lavender','oak','chocolate'], 
               'group' : [1,1,1,1,1,
                          1,1,1,1,1,
                          1,2,2,2,2,
                          4,4,5,6,7]})
df = df.set_index('color')
df

对于此数据,我想为a中的每个唯一值应用一个特殊计数器。以下是我当前的实现:

df['C'] = 0
for value in set(df['group'].values):
    filtered_df = df[df['group'] == value]
    adj_counter = 0
    initialize_counter = -1
    spacing_counter = 20
    special_counters = [0,1,-1,2,-2,3,-3,4,-4,5,-5,6,-6,7,-7]
    for color,rows in filtered_df.iterrows():
        if len(filtered_df.index) < 7:
            initialize_counter +=1
            df.loc[color,'C'] = (46+special_counters[initialize_counter])

        else:
            spacing_counter +=1
            if spacing_counter > 5:
                spacing_counter = 0
            df.loc[color,'C'] = spacing_counter
df
df['C']=0
对于集合中的值(df['group'].值):
过滤的_df=df[df['group']==value]
调整计数器=0
初始化\u计数器=-1
间隔计数器=20
特殊_计数器=[0,1,-1,2,-2,3,-3,4,-4,5,-5,6,-6,7]
对于颜色,过滤的_df.iterrows()中的行:
如果len(过滤的测向索引)<7:
初始化计数器+=1
df.loc[color,'C']=(46+特殊计数器[初始化计数器])
其他:
计数器+=1的间距
如果间隔计数器>5:
间距_计数器=0
df.loc[颜色,'C']=间距计数器
df


有没有一种更快的方法来实现这一点,而不涉及iTerrow或itertuples?由于C列中的计数非常不规则,我不确定如何通过应用甚至矢量化来实现这一点,您可以做的是首先在列“group”和
cumcount
上使用
groupby
创建列“C”,这几乎表示
间距计数器
初始化计数器
,具体取决于
如果len(过滤后的测向索引)<7

df['C'] = df.groupby('group').cumcount()
现在,您需要选择适当的行来执行代码的
if
else
部分。一种方法是再次使用
groupby
创建一个系列,然后
transform
以了解与每行相关的组的
大小。然后,使用
loc
对您
df
使用此系列并执行:if该值小于7,您可以使用
特殊计数器
映射您的值,否则只需使用模
%
6即可

ser_size = df.groupby('group')['C'].transform('size')
df.loc[ser_size < 7,'C'] = df.loc[ser_size < 7,'C'].map(lambda x: 46 + special_counters[x])
df.loc[ser_size >= 7,'C'] %= 6

为什么计数器返回到零,其中
color==“black”
?你能用文字解释一下计数器应该做什么吗?
print (df)
            group   C
color                
red             1   0
blue            1   1
yellow          1   2
orange          1   3
green           1   4
white           1   5
black           1   0
brown           1   1
orange-red      1   2
teal            1   3
beige           1   4
mauve           2  46
cyan            2  47
goldenrod       2  45
auburn          2  48
azure           4  46
celadon         4  47
lavender        5  46
oak             6  46
chocolate       7  46