简体   繁体   English

将循环中的 where 应用到不同的列集的更有效方法 - python

[英]more efficient way of apply where in a loop to different sets of columns - python

I want cross tabs for columns 'month', 'week' and 'year' against column 'a', but i only want to replace values 0 and 1 for columns 'month' and 'week'.我想要“月”、“周”和“年”列与“a”列的交叉表,但我只想替换“月”和“周”列的值 0 和 1。 I have a code below that does technically work, but i was wondering if there was a more efficient way of writing it?我下面有一个在技术上可行的代码,但我想知道是否有更有效的编写方式? any pointers would be great!任何指针都会很棒! thank you谢谢

import pandas as pd
import numpy as np 

out = {}
df = pd.DataFrame({'a': ['a','b','b','a','b','b','a','b','a'], 
                   'month':['march','march','january', 'march','january','january', 'may','march','march'],
                   'week':['1','1','1', '1','2','3', '3','2','1'],
                   'year':['5','3','4', '3','1','1', '1','1','1']})

cols_a =['month', 'week']
cols_b = ['year']

out1 = {}
out2={}

for col in cols_a:
    ct1 = pd.crosstab(df.a, df[col])
    ct2 = pd.DataFrame(ct1.where(ct1 >=2, 'group_a'))
    out1[f'{(col)}'] = ct2

for col in cols_b:
    ct3 =  pd.crosstab(df.a, df[col])
    out2[f'{(col)}'] = ct3

out3 = {**out1, **out2}

the current output looks like this, which is correct当前输出看起来像这样,这是正确的

{'month': month  january  march      may
 a                             
 a      group_a      3  group_a
 b            3      2  group_a,
 'week': week  1        2        3
 a                        
 a     3  group_a  group_a
 b     2        2  group_a,
 'year': year  1        3        4        5
 a                                 
 a     2  1  0  1
 b     3  1  1  0}

Idea is join list and use where only for columns if exist in cols_a :想法是连接列表,如果cols_a存在列,则仅使用where

cols_a = ['month', 'week']
cols_b = ['year']

out = {}
for col in cols_a + cols_b:
    ct1 = pd.crosstab(df.a, df[col])
    if col in cols_a:
        ct1 = ct1.where(ct1 >=2, 'group_a')
    out[f'{(col)}'] = ct1

Not revolutionary different, but here is a solution in form of a dict comprehension :没有革命性的不同,但这里有一个字典理解形式的解决方案:

{k: pd.crosstab(df['a'], df[k]).applymap(lambda x: 'group_a' if x<2 else x)
    if k in cols_a else
    pd.crosstab(df['a'], df[k])
 for k in cols_a+cols_b
}

output:输出:

{'month': month  january  march      may
 a                             
 a      group_a      3  group_a
 b            3      2  group_a,
 'week': week  1        2        3
 a                        
 a     3  group_a  group_a
 b     2        2  group_a,
 'year': year  1  3  4  5
 a               
 a     2  1  0  1
 b     3  1  1  0}

Here is an alternative to avoid the applymap :这是避免applymap的替代方法:

def group_a(df):
    return df.where(df >= 2, 'group_a')

{k: pd.crosstab(df['a'], df[k]).transform(group_a)
    if k in cols_a else
    pd.crosstab(df['a'], df[k])
 for k in cols_a+cols_b}

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

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