0

Python“Exec”命令未在 exec shell 中传递本地值。我认为这应该是一个简单的问题,但似乎所有人都难住了。这是问题的可重复工作版本......我花了一点时间来重新创建一个工作问题(我的文件比这里显示的示例大得多,每个循环最多有 10-dfs,每个 df 通常有 1800 个项目)

在我添加“”之前,EXEC 只传递了“PRODUCT”(与“PRODUCT.AREA”相反["{ind_id}"],然后它也显示了一个错误“ <string> in <module>”。

datum_0 = {'Products':  ['Stocks', 'Bonds', 'Notes'],'PRODUCT.AREA': ['10200', '50291','50988']}
df_0 = pd.DataFrame (datum_0, columns = ['Products','PRODUCT.AREA'])
datum_1 = {'Products':  ['Stocks', 'Bonds', 'Notes'],'PRODUCT.CODE': ['66', '55','22']}
df_1 = pd.DataFrame (datum_1, columns = ['Products','PRODUCT.CODE'])
df_0

在此处输入图像描述

在此处输入图像描述

summary = {'Prodinfo':  ['PRODUCT.AREA', 'PRODUCT.CODE']}
df_list= pd.DataFrame (summary, columns = ['Prodinfo'])
df_list

在此处输入图像描述

# Create a rankings column for the Prodinfo tables
for rows in df_list.itertuples():
    row = rows.Index
    ind_id = df_list.loc[row]['Prodinfo']
    print(row, ind_id)
    exec(f'df_{row}["rank"] = df_{row}["{ind_id}"].rank(ascending=True) ')

当然,这是引发 exec 错误的最后一行。有任何想法吗?你有一个有效的全局或局部变量赋值来修复它吗?等等...谢谢!

4

2 回答 2

2

我会使用 list 来保留所有 DataFrame

all_df = [] # list
all_df.append(df_1)
all_df.append(df_2)

然后我就不需要了exec

for rows in df_list.itertuples():
    row = rows.Index
    ind_id = df_list.loc[row]['Prodinfo']
    print(row, ind_id)
    all_df[row]["rank"] = all_df[row][ind_id].rank(ascending=True)

最终我会使用字典

all_df = {} # dict
all_df['PRODUCT.AREA'] = df_1
all_df['PRODUCT.CODE'] = df_2

然后我不需要execdf_list

for key, df in all_df.items():
    df["rank"] = df[key].rank(ascending=True)

最少的工作代码list

import pandas as pd

all_df = [] # list

datum = {
    'Products': ['Stocks', 'Bonds', 'Notes'],
    'PRODUCT.AREA': ['10200', '50291', '50988']
}
all_df.append( pd.DataFrame(datum) )

datum = {
    'Products': ['Stocks', 'Bonds', 'Notes'],
    'PRODUCT.CODE': ['66', '55', '22']
}
all_df.append( pd.DataFrame(datum) )

#print( all_df[0] )
#print( all_df[1] )

print('--- before ---')
for df in all_df:
    print(df)

summary = {'Prodinfo': ['PRODUCT.AREA', 'PRODUCT.CODE']}
df_list = pd.DataFrame(summary, columns=['Prodinfo'])
#print(df_list)

for rows in df_list.itertuples():
    row = rows.Index
    ind_id = df_list.loc[row]['Prodinfo']
    #print(row, ind_id)
    all_df[row]["rank"] = all_df[row][ind_id].rank(ascending=True)

print('--- after ---')
for df in all_df:
    print(df)

最少的工作代码dict

import pandas as pd

all_df = {} # dict

datum = {
    'Products': ['Stocks', 'Bonds', 'Notes'],
    'PRODUCT.AREA': ['10200', '50291', '50988']
}
all_df['PRODUCT.AREA'] = pd.DataFrame(datum)


datum = {
    'Products': ['Stocks', 'Bonds', 'Notes'],
    'PRODUCT.CODE': ['66', '55', '22']
}
all_df['PRODUCT.CODE'] = pd.DataFrame (datum)

print('--- before ---')
for df in all_df.values():
    print(df)

for key, df in all_df.items():
    df["rank"] = df[key].rank(ascending=True)

print('--- after ---')
for df in all_df.values():
    print(df)

坦率地说,对于两个数据帧,我不会浪费时间 fordf_listfor-loop

import pandas as pd

datum = {
    'Products': ['Stocks', 'Bonds', 'Notes'],
    'PRODUCT.AREA': ['10200', '50291', '50988']
}
df_0 = pd.DataFrame(datum)

datum = {
    'Products': ['Stocks', 'Bonds', 'Notes'],
    'PRODUCT.CODE': ['66', '55', '22']
}
df_1 = pd.DataFrame(datum)

print('--- before ---')
print( df_0 )
print( df_1 )

df_0["rank"] = df_0['PRODUCT.AREA'].rank(ascending=True)    
df_1["rank"] = df_1['PRODUCT.CODE'].rank(ascending=True)    

print('--- after ---')
print( df_0 )
print( df_1 )

也许我什至会将所有内容放在一个数据框中

import pandas as pd

df = pd.DataFrame({
    'Products': ['Stocks', 'Bonds', 'Notes'],
    'PRODUCT.AREA': ['10200', '50291', '50988'],
    'PRODUCT.CODE': ['66', '55', '22'],
})

print('--- before ---')
print( df )

#df["rank PRODUCT.AREA"] = df['PRODUCT.AREA'].rank(ascending=True)    
#df["rank PRODUCT.CODE"] = df['PRODUCT.CODE'].rank(ascending=True)    

for name in ['PRODUCT.AREA', 'PRODUCT.CODE']:
    df[f"rank {name}"] = df[name].rank(ascending=True)    

print('--- after ---')
print( df )

结果:

--- before ---
  Products PRODUCT.AREA PRODUCT.CODE
0   Stocks        10200           66
1    Bonds        50291           55
2    Notes        50988           22
--- after ---
  Products PRODUCT.AREA PRODUCT.CODE  rank PRODUCT.AREA  rank PRODUCT.CODE
0   Stocks        10200           66                1.0                3.0
1    Bonds        50291           55                2.0                2.0
2    Notes        50988           22                3.0                1.0
于 2020-06-12T04:42:57.847 回答
1

正如预期的那样,这是一个简单的修复。感谢回答者给予了很多思考......

感谢@holdenweb 和他的回答...在循环中创建多个数据框

dfnew = {}  # CREATE A DICTIONARY!!! - THIS WAS THE TRICK I WAS MISSING
df_ = {}
for rows in df_list.itertuples():
    row = rows.Index
    ind_id = df_list.loc[row]['Prodinfo']
    dfnew[row] = df_[row] # or pd.read_csv(csv_file) or database_query or ...
    dfnew[row].dropna(inplace=True)
    dfnew[row]["rank"] = dfnew[row][ind_id].rank(ascending=True)

效果很好而且非常简单......

于 2020-06-12T07:38:12.570 回答