Создать панд DFS в течение цикла - PullRequest
1 голос
/ 11 октября 2019

У меня есть следующий фрейм данных:

import pandas as pd
df = pd.DataFrame({'name':['apple', 'banana', 'apple', 'mandarin', 'kiwi', 'kiwi'], 'val':[1,5,3,4,5,3]})

Я хочу создать отдельные фреймы данных, передавая имя плода следующей функции:

def split_all_fruits(df, fruit):
    return df[df['name'] == fruit]

Затем я могу создать фреймы данных, просто вызывая функцию:

apple_df = split_all_fruits(df, 'apple')
banana_df = split_all_fruits(df, 'banana')
#and other fruits

Но я бы хотел создать циклы данных для цикла for без вызова funtion каждый раз для каждого фрукта. Но возможно ли создать цикл for, который выдает 5 фреймов данных с именем фрейма данных из списка сразу для каждого фрукта? Примерно так:

#name of dfs
name_of_dfs = ['apple_df', 'banana_df', 'mandarin_df', 'kiwi_df']
#fruit names in df
fruit_name = ['apple', 'banana', 'mandarin', 'kiwi']
#loop to create dfs, but i dont know how to assign list of names in name_of_dfs to respective fruit df
for fruit in fruit_name:
    df_final = split_all_fruits(df,fruit)
    print(df_final)
#it prints all dfs together, but not seperate df with name from list

Спасибо!

Ответы [ 4 ]

1 голос
/ 11 октября 2019

Если вы хотите, чтобы имена переменных вместо ключей словаря (не очень хорошая идея, но об этом спрашивал ОП), вы можете использовать exec().

#name of dfs
name_of_dfs = ['apple_df', 'banana_df', 'mandarin_df', 'kiwi_df']
fruit_name = ['apple', 'banana', 'mandarin', 'kiwi']

for fruit, df_name in zip(fruit_name, name_of_dfs):
    exec(f'{df_name} = split_all_fruits(df, "{fruit}")')
    print(globals()[df_name])

Теперь вы можете получить доступ к переменной напрямую:

print(apple_df)

    name  val
0  apple    1
2  apple    3
1 голос
/ 11 октября 2019

Если вы хотите сгенерировать фрейм данных для каждого фрукта, вы можете использовать следующее (отмечая, что порядок будет в алфавитном порядке в соответствии с названиями фруктов):

[d for name, d in df.groupby("name")]

Если вам нужен список в вашемконкретный порядок:

[df.query("name == '{}'".format(f)) for f in fruit_name]

Если вы хотите иметь доступ к ним по имени, вы можете использовать словарь и ссылаться на название фрукта:

grouped = {name: d for name, d in df.groupby("name")}

# e.g. for apple:
apple_df = grouped['apple']

Наконец, если вам нужноперечислить конкретные переменные и знать, что они должны быть опережающими:

grouped = {name: d for name, d in df.groupby("name")}

apple_df, banana_df, mandarin_df, kiwi_df = [grouped[fruit] for fruit in fruit_name]
1 голос
/ 11 октября 2019

Хотя это можно сделать с помощью eval() или globals(), гораздо лучше (чище, проще для программного управления) использовать вместо него dict, например:

dfs = {name: split_all_fruits(df, name) for name in fruit_name}

длябыть доступным, например:

dfs['apple']

РЕДАКТИРОВАТЬ

Если вы REALLY хотите иметь переменные с именем apple_df и т. д. сделать это можно, изменив словарь globals(), например:

globals().update({name + '_df': split_all_fruits(df, name) for name in fruit_name})

, к которому необходимо получить доступ, например:

apple_df

Будьте осторожны, хотя это считается плохой практикой!

0 голосов
/ 11 октября 2019

Вы можете изменить свой последний фрагмент кода, как показано ниже:

name_of_dfs = ['apple_df', 'banana_df', 'mandarin_df', 'kiwi_df']
#fruit names in df
fruit_name = ['apple', 'banana', 'mandarin', 'kiwi']
dfs = {}
#loop to create dfs, but i dont know how to assign list of names in name_of_dfs to respective fruit df
for fruit in fruit_name:
    df_final = split_all_fruits(df,fruit)
    dfs[fruit] = df_final
    print(df_final)

Затем, получить доступ к любому фрейму данных, используя имя плода.

dfs['apple']
...