繁体   English   中英

根据列值将值从一个数据帧映射到其他数据帧中的新列 - Pandas

[英]Map values from one dataframe to new columns in other based on column values - Pandas

我从另一个数据帧映射值时遇到问题。

这些是两个数据帧的样本:

DF1

product   class_1   class_2   class_3
141A        11        13         5     
53F4        12        11        18  
GS24        14        12        10   

DF2

id    product_type_0  product_type_1 product_type_2  product_type_3 measure_0 measure_1 measure_2   measure_3
1         141A            GS24             NaN           NaN          1         3           NaN       NaN
2         53F4            NaN              NaN           NaN          1        NaN          NaN       NaN
3         53F4            141A             141A          NaN          2         2            1        NaN
4         141A            GS24             NaN           NaN          3         2           NaN       NaN

我接下来要做的是:我需要添加一个名为“Max_Class_1”,“Max_Class_2”,“Max_Class_3”的新列,并且该值将从df1中获取。 对于每个订单号(_1,_2,_3),请查看现有列(例如product_type_1)product_type_1,并从产品具有相同值的df1中获取一行。 然后查看度量列(例如measure_1),如果值为1(原始数据中可能最多有四个不同的值),则名为“Max_Class_1”的新列将具有与该product_type的class_1相同的值,在本例中为11。

我认为这比我解释的要简单一些。

期望的输出

id    product_type_0  product_type_1 product_type_2  product_type_3  measure_0 measure_1 measure_2  measure_3  max_class_0  max_class_1  max_class_2  max_class_3
1         141A            GS24             NaN         NaN            1         3         NaN        NaN        1           10            NaN NaN
2         53F4            NaN              NaN         NaN            1        NaN        NaN        NaN        12         NaN           NaN  NaN
3         53F4            141A             141A        NaN            2         2         1          NaN        11          13            11  NaN
4         141A            GS24             NaN         NaN            3         2         NaN        NaN        5           12            NaN NaN

我试过的代码:

df2['max_class_1'] = None
df2['max_class_2'] = None
df2['max_class_3'] = None

def get_max_class(product_df, measure_df, product_type_column, measure_column, max_class_columns):
    for index, row in measure_df.iterrows():
        product_df_new = product_df[product_df['product'] == row[product_type_column]]
        for ind, r in product_df_new.iterrows():
            if row[measure_column] == 1:
                row[max_class_columns] = r['class_1']
            elif row[measure_column] == 2:
                row[max_class_columns] = r['class_2']
            elif row[measure_column] == 3:
                row[max_class_columns] = r['class_3']
            else:
                row[tilt_column] = "There is no measure or type"
    return measure_df

# And the function call 
first_class = get_max_class(product_df=df1, measure_df=df2, product_type_column=product_type_1, measure_column='measure_1', max_class_columns='max_class_1')

second_class = get_max_class(product_df=df1, measure_df=first_class, product_type_column=product_type_2, measure_column='measure_2', max_class_columns='max_class_2')

third_class = get_max_class(product_df=df1, measure_df=second_class, product_type_column=product_type_3, measure_column='measure_3', max_class_columns='max_class_3')

我很确定有一个更简单的解决方案,但不知道为什么不起作用。 我得到所有无价值,没有任何变化。

pd.DataFrame.lookup是按行和列标签查找的标准方法。

存在空值会使您的问题变得复杂。 但这可以通过修改输入映射数据帧来适应。

步骤1

df1列重命名为整数并添加一个额外的行/列。 稍后我们将使用添加的数据来处理空值。

def rename_cols(x):
    return x if not x.startswith('class') else int(x.split('_')[-1])

df1 = df1.rename(columns=rename_cols)

df1 = df1.set_index('product')
df1.loc['X'] = 0
df1[0] = 0

您的映射数据框现在看起来像:

print(df1)

          1   2   3  0
product               
141A     11  13   5  0
53F4     12  11  18  0
GS24     14  12  10  0
X         0   0   0  0

第2步

迭代类别数量并使用pd.DataFrame.lookup 注意我们如何fillna X0 ,正是我们在步骤1中用于附加映射数据的内容。

n = df2.columns.str.startswith('measure').sum()

for i in range(n):
    rows = df2['product_type_{}'.format(i)].fillna('X')
    cols = df2['measure_{}'.format(i)].fillna(0).astype(int)
    df2['max_{}'.format(i)] = df1.lookup(rows, cols)

结果

print(df2)

   id product_type_0 product_type_1 product_type_2  product_type_3  measure_0  \
0   1           141A           GS24            NaN             NaN          1   
1   2           53F4            NaN            NaN             NaN          1   
2   3           53F4           141A           141A             NaN          2   
3   4           141A           GS24            NaN             NaN          3   

   measure_1  measure_2  measure_3  max_0  max_1  max_2  max_3  
0        3.0        NaN        NaN     11     10      0      0  
1        NaN        NaN        NaN     12      0      0      0  
2        2.0        1.0        NaN     11     13     11      0  
3        2.0        NaN        NaN      5     12      0      0  

如果需要,您可以将0转换为np.nan 这将以将系列从int转换为float为代价,因为NaN被认为是float

当然,如果X0是有效值,您可以从一开始就使用替代填充值。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM