如何根据另一个数据帧中定义的行/列缩放因子缩放数据帧?

2024-09-24 02:20:29 发布

您现在位置:Python中文网/ 问答频道 /正文

因此,我提取了2个数据帧,如下所示:
DF1:enter image description here

DF2:enter image description here

我希望基于另一个数据帧中的条件匹配,将一个因子应用于DF1的pricedata 1和pricedata2列的不同部分

例如,对于DF1中的第0行,我希望在pricedata1值100.5上应用一个因子,方法是根据DF1列年份值==DF2列名称和DF1列名称==DF2 pricename列值的条件乘以从DF2派生的2.5。然后在2007年对pricedata1应用另一个因子5

我知道如何对整个列使用df.apply,但对于如何根据不同的if条件将其部分应用于列,我感到非常困惑

期望输出: enter image description here

提前谢谢


Tags: 数据方法名称df条件因子df1apply
3条回答

一个简洁的解决方案是^{}你的df2df1上。首先重塑df2以匹配df1(年份作为行,价格名称作为列),然后reindex()并按元素乘以比例因子

注意:这取决于两个索引具有相同的数据类型,因此根据需要转换year.astype(...)

df2 = df2.set_index('pricename').T.reindex(df1.year)

df1.pricedata1 = df1.pricedata1 * df2.pricedata1.values
df1.pricedata2 = df1.pricedata2 * df2.pricedata2.values

#       date  year  pricedata1  pricedata2
# 2006-01-02  2006      251.25       169.5
# 2006-01-03  2006      251.25       169.5
# 2006-01-04  2006      251.25       169.5
# 2006-01-05  2006      251.25       169.5
# 2006-01-06  2006      251.25       169.5
# 2006-01-07  2006      251.25       169.5
# 2006-01-08  2006      251.25       169.5
# 2006-01-09  2006      251.25       169.5
# 2006-01-10  2006      251.25       169.5
# 2006-01-11  2006      251.25       169.5
# 2006-01-12  2006      251.25       169.5
# 2006-01-13  2006      251.25       169.5
# 2006-01-14  2006      251.25       169.5
# 2006-01-15  2006      251.25       169.5
# 2007-01-02  2007      502.50       339.0
# 2007-01-03  2007      502.50       339.0
# 2007-01-04  2007      502.50       339.0
# 2007-01-05  2007      502.50       339.0

您可以通过按行应用df1来实现这一点:

def multiply(row):
    year = df1['year'].loc[row.name]

    for pricedata in row.index:
        row[pricedata] = df2[str(year)].loc[pricedata] * row[pricedata]

    return row

df1[['pricedata1', 'pricedata2']].apply(multiply, axis=1)

中波

import sys
import pandas as pd
from io import StringIO

TESTDATA = StringIO("""year pricedata1 pricedata2
2016 100.5 56.5
2017 100.5 56.5
    """)

df1 = pd.read_csv(TESTDATA, delim_whitespace=True)

TESTDATA = StringIO("""pricename 2016 2017
pricedata1 2.5 5
pricedata2 3.0 6
    """)

df2 = pd.read_csv(TESTDATA, delim_whitespace=True)

df2 = df2.set_index('pricename')

def multiply(row):
    year = df1['year'].loc[row.name]

    for pricedata in row.index:
        row[pricedata] = df2[str(year)].loc[pricedata] * row[pricedata]

    return row

df1[['pricedata1', 'pricedata2']] = df1[['pricedata1', 'pricedata2']].apply(multiply, axis=1)
# print(df1)

   year  pricedata1  pricedata2
0  2016      251.25       169.5
1  2017      502.50       339.0

此代码的工作逻辑如下:

沿着row in df1进行迭代,并在df2.iloc[0].iloc[coln.index(j)]的帮助下更新i-th row
其中,
coln=列表(df2.列);df2的列,我们将在未来的迭代匹配中使用它。
coln.指数(j);给出j的指数,其中j是年
.

有用的代码就在这一部分。剩下的我用来从头开始制作dataframe

coln = list(df2.columns)

for i,j in zip(range(18),df1['year']):
    df1['pricedata1'][i] = df1['pricedata1'][i]*df2.iloc[0].iloc[coln.index(j)]
    df1['pricedata2'][i] = df1['pricedata2'][i]*df2.iloc[1].iloc[coln.index(j)]

print(df1)

完整代码:

import pandas as pd

days_2006 = pd.Series(
    pd.date_range("2006-01-02", periods=14, freq="D")
)

days_2007 = pd.Series(
    pd.date_range("2007-01-02", periods=4, freq="D")
)

days_total = pd.concat([days_2006, days_2007], ignore_index=True)

df1 = pd.DataFrame(
    data= {
        'date': days_total,
        'year':days_total.dt.year,
        'pricedata1': [100.5]*18,
        'pricedata2': [56.5]*18
    },
)

df2 = pd.DataFrame(
    data={
        'pricename':['pricedata1', 'pricedata2'],
        2006:[2.5, 3.0],
        2007:[5.0, 6.0]
    }
)

coln = list(df2.columns)

for i,j in zip(range(18),df1['year']):
    df1['pricedata1'][i] = df1['pricedata1'][i]*df2.iloc[0].iloc[coln.index(j)]
    df1['pricedata2'][i] = df1['pricedata2'][i]*df2.iloc[1].iloc[coln.index(j)]

print(df1)

相关问题 更多 >