根据选择的列值划分组数据库?

2024-10-01 13:28:17 发布

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

df

   ts_code    type  close

  0 861001.TI   1   648.399
  1 861001.TI   20  588.574
  2 861001.TI   30  621.926
  3 861001.TI   60  760.623
  4 861001.TI   90  682.313
  ...   ... ... ...
  8328  885933.TI   5   1083.141
  8329  885934.TI   1   951.493
  8330  885934.TI   5   1011.346
  8331  885935.TI   1   1086.558
  8332  885935.TI   5   1028.449

目标

ts_code    l5d_close l20d_close …… l90d_close
861001.TI   NaN       1.10          0.95
……           ……       ……            ……

我想按ts_code分组以计算type(1)close/计算type(N:5,20,30……)close。以861001.TI为例,l5d_close是nan,因为当类型为5时没有值l20d_close等于648.399/588.574=1.10,{}等于648.399/682.313=0.95。结果是四舍五入的

试一试

df.groupby('ts_code')\
  .pipe(lambda x: x[x.type==1].close/x[x.type==10].close)

Got: KeyError: 'Column not found: False'

类型值为:1,5,20,30,60,90180200

注意:每个ts_code有一个type列的值


Tags: 类型目标dfclosetypeticodenan
3条回答

嗯,我认为您不需要在这里分组,因为您并没有真正分组或使用任何聚合功能。
我认为使用函数创建一个新的DF会更容易

ts_codes = df.ts_code.unique()
types = [5,20,30,60,90,180,200]
ts_results = []
for ts_code in ts_codes:
    ts_result = [ts_code]
    temp = df.loc[df.tscode == ts_code]
    val_1 = temp.loc[df.type == 1]['close'].iloc[0] # to get the actual value 
    for type in types:
        val = temp.loc[df.type == type]
        if len(val) > 0:
            ts_result.append(val_1/val)
        else:
            ts_result.append(None)
    ts_results.append(ts_result)
results_df = pd.DataFrame(ts_results,coluns=['ts_code','l5d_close', 'l20d_close' …… 'l90d_close']

我没有运行代码来获得结果,因为您没有提供一种简单的方法来生成数据,希望这能有所帮助

很抱歉,但有时简单的解决方案是最好的(我会将其移动到函数)

使用^{}确保type == 1是每个组的第一行,并使用^{}提取它们:

df = df.sort_values(['ts_code', 'type'])
close1 = df.groupby('ts_code')['close'].transform('first')
df['close'] = close1 / df['close']

#         ts_code  type     close
# 0     861001.TI     1  1.000000
# 1     861001.TI    20  1.101644
# 2     861001.TI    30  1.042566
# 3     861001.TI    60  0.852458
# ...         ...   ...       ...

然后^{}type列插入列标题:

out = (df.pivot(index='ts_code', columns='type', values='close')
         .drop(columns=1)
         .add_prefix('l')
         .add_suffix('d_close'))

# type       l5d_close  l20d_close  l30d_close  l60d_close  l90d_close
# ts_code
# 861001.TI        NaN    1.101644    1.042566    0.852458    0.950296
# ...              ...         ...         ...         ...         ...

要链接在一起,^{}^{}之前的ratio列:

(df.assign(ratio=df.groupby('ts_code').close.transform('first').div(df.close))
   .pivot(index='ts_code', columns='type', values='ratio')
   .drop(columns=1)
   .add_prefix('l')
   .add_suffix('d_close'))

# type       l5d_close  l20d_close  l30d_close  l60d_close  l90d_close
# ts_code
# 861001.TI        NaN    1.101644    1.042566    0.852458    0.950296
# ...              ...         ...         ...         ...         ...

您可以使用pandas.DataFrame.pivot_table()docs)执行此操作。只要每个type一些数据,就会创建该列

pivoted = (
    df.pivot_table(values=["close"], index="ts_code", columns="type")
    # get rid of the first MultiIndex level
    .droplevel(0, axis=1)
    # divide type == 1 column values by every other column
    .pipe(lambda f: f[[1]].values / f.iloc[:, 1:])
    .round(2)
)

# format column names
pivoted.columns = "l" + pivoted.columns.astype(str) + "d_close"
pivoted

这将返回:

type       l5d_close  l20d_close  l30d_close  l60d_close  l90d_close
ts_code                                                             
861001.TI        NaN    1.101644    1.042566    0.852458    0.950296
885933.TI        NaN         NaN         NaN         NaN         NaN
885934.TI   0.940818         NaN         NaN         NaN         NaN
885935.TI   1.056502         NaN         NaN         NaN         NaN

相关问题 更多 >