简体   繁体   English

基于来自另一个数据框的其他列创建新列

[英]Creating a new column based on other columns from another dataframe

I have 2 dataframes:我有2个数据框:

df1 df1

Name   Apples   Pears   Grapes   Peachs
James    3       5        5        2
Harry    1       0        2        9
Will     20      2        7        3

df2 df2

Class   User   Factor  
A       Harry  3
A       Will   2
A       James  5
B       NaN    4

I want to create a new column in df2 called Total which is a list of all the columns for each user in df1, multiplied by the Factor for that user - this should only be done if they are in Class A.我想在 df2 中创建一个名为Total的新列,它是 df1 中每个用户的所有列的列表,乘以该用户的因子 - 只有当它们在 A 类中时才应该这样做。

This is how the final df should look这就是最终 df 的样子

df2 df2

Class   User   Factor   Total 
A       Harry  3        [3,0,6,27]
A       Will   2        [40,4,14,6]
A       James  5        [15,25,25,10]
B       NaN    4

This is what I tried:这是我尝试过的:

df2['Total'] = list(df1.Name.isin((df2.User) and (df2.Class==A)) * df2.Factor)

You can use:您可以使用:

# First lookup
factor = df2[df2['Class'] == 'A'].set_index('User')['Factor']
df1['Total'] = df1[cols].mul(df1['Name'].map(factor), axis=0).agg(list, axis=1)

# Second lookup
df2['Total'] = df2['User'].map(df1.set_index('Name')['Total'])

Output:输出:

>>> df2
  Class   User  Factor             Total
0     A  Harry       3     [3, 0, 6, 27]
1     A   Will       2    [40, 4, 14, 6]
2     A  James       5  [15, 25, 25, 10]
3     B    NaN       4               NaN

>>> df1
    Name  Apples  Pears  Grapes  Peachs             Total
0  James       3      5       5       2  [15, 25, 25, 10]
1  Harry       1      0       2       9     [3, 0, 6, 27]
2   Will      20      2       7       3    [40, 4, 14, 6]

This will do what your question asks:这将满足您的问题:

df2 = df2[df2.Class=='A'].join(df.set_index('Name'), on='User').set_index(['Class','User'])
df2['Total'] = df2.apply(lambda x: list(x * x.Factor)[1:], axis=1)
df2 = df2.reset_index()[['Class','User','Factor','Total']]

Full test code:完整的测试代码:

import pandas as pd
import numpy as np
df = pd.DataFrame(columns=[
x.strip() for x in 'Name   Apples   Pears   Grapes   Peachs'.split()], data =[
['James',    3,       5,        5,        2],
['Harry',   1,       0,        2,        9],
['Will',     20,      2,        7,        3]])
print(df)

df2 = pd.DataFrame(columns=[
x.strip() for x in 'Class   User   Factor'.split()], data =[
['A',       'Harry',  3],
['A',       'Will',   2],
['A',       'James',  5],
['B',       np.nan,    4]])
print(df2)

df2 = df2[df2.Class=='A'].join(df.set_index('Name'), on='User').set_index(['Class','User'])
df2['Total'] = df2.apply(lambda x: list(x * x.Factor)[1:], axis=1)
df2 = df2.reset_index()[['Class','User','Factor','Total']]
print(df2)

Input:输入:

    Name  Apples  Pears  Grapes  Peachs
0  James       3      5       5       2
1  Harry       1      0       2       9
2   Will      20      2       7       3
  Class   User  Factor
0     A  Harry       3
1     A   Will       2
2     A  James       5
3     B    NaN       4

Output输出

  Class   User  Factor             Total
0     A  Harry       3     [3, 0, 6, 27]
1     A   Will       2    [40, 4, 14, 6]
2     A  James       5  [15, 25, 25, 10]

On-liner masochists, greetings ;)在线受虐狂,问候 ;)

df2['Total'] = pd.Series(df1.sort_values(by='Name').reset_index(drop=True).iloc[:,1:5]\
                         .mul(df2[df2.Class == 'A'].sort_values(by='User')['Factor'].reset_index(drop=True), axis=0)\
                         .values.tolist())
df2

Output:输出:

index指数 Class班级 User用户 Factor因素 Total全部的
0 0 A一个 Harry哈利 3 3 3,0,6,27 3,0,6,27
1 1 A一个 Will将要 2 2 15,25,25,10 15,25,25,10
2 2 A一个 James詹姆士 5 5 40,4,14,6 40,4,14,6
3 3 B NaN 4 4 NaN

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

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