Создайте новый столбец, заполненный именем переменной в Python - PullRequest
0 голосов
/ 29 мая 2018

Предположим, у меня есть фрейм данных:

df = quandl.get("FRED/DEXBZUS")

Вывод будет:

print(df)

    Year    Value
1995-01-02  0.8440
1995-01-03  0.8450
1995-01-04  0.8450
1995-01-05  0.8430
1995-01-06  0.8400
1995-01-09  0.8440
1995-01-10  0.8470
1995-01-11  0.8510

Я пытаюсь создать новый столбец, заполненный именем переменной:

print(df)

    Year     Value  Variable
1995-01-02  0.8440    df
1995-01-03  0.8450    df
1995-01-04  0.8450    df
1995-01-05  0.8430    df
1995-01-06  0.8400    df
1995-01-09  0.8440    df
1995-01-10  0.8470    df
1995-01-11  0.8510    df

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

df = quandl.get("FRED/DEXBZUS")
df2 = quandl.get("FRED/DEXBZUS")

data = [df, df2]

for i in data:

dps = []

for i in df:
        d = i.reset_index()
        d = pd.DataFrame(d)
        d['variable'] = [i]

Но я не получил имя переменной внутри столбцов.

Должно быть так:

    Year     Value  Variable
1995-01-02  0.8440    df
1995-01-03  0.8450    df
1995-01-04  0.8450    df
1995-01-05  0.8430    df
1995-01-06  0.8400    df
1995-01-09  0.8440    df
1995-01-10  0.8470    df
1995-01-11  0.8510    df


2008-01-02  0.8440    df2
2008-01-03  0.8450    df2
2008-01-04  0.8450    df2
2008-01-05  0.8430    df2
2008-01-06  0.8400    df2
2008-01-09  0.8440    df2
2008-01-10  0.8470    df2
2008-01-11  0.8510    df2

Ответы [ 2 ]

0 голосов
/ 29 мая 2018

Чтобы получить имя переменной, мы можем использовать код из этого ответа , скопированный ниже:

import inspect


def retrieve_name(var):
        """
        Gets the name of var. Does it from the out most frame inner-wards.
        :param var: variable to get name from.
        :return: string
        """
        for fi in reversed(inspect.stack()):
            names = [var_name for var_name, var_val in fi.frame.f_locals.items() if var_val is var]
            if len(names) > 0:
                return names[0]

Проблема в том, что она не будет работать, когдаперебирая, скажем, список, потому что вы просто получите имя локальной переменной.Это связано с тем, как имена переменных работают в python.Переменная указывает на объект, то есть место в памяти, но место в памяти не указывает назад.Это означает, что для данного объекта вы не можете определить его имя.То же самое верно для контейнеров, таких как списки.Если, например, у вас есть список l, который содержит два объекта a и b l=[a,b], список фактически не сохраняет имена переменных a и b.Вместо этого, когда вы создаете список, он записывает место в памяти, на которое указывают a и b, то есть объекты, а не имена.

d = 'a'
print(retrieve_name(d))
#'d'
l = [d, d]
print([retrieve_name(element) for element in list ])
#['element', 'element']

При этом, если у вас есть словарь имен и объектов, вы можете делать то, что вы просили:

name_dict = {'df': df, 'df2':df2}
dfs = [frame.assign(Variable=name) for name, frame in name_dict.items()]
combined_df = pd.concat(dfs)

Однако, если все ваши фреймы данных имеют разные данныеИсточники, то есть более простой способ сделать все это.Я часто сталкиваюсь с проблемой наличия данных в нескольких разных источниках, и их имена, например, имена файлов.Допустим, у меня есть несколько файлов .csv, из которых я читаю данные, и я хочу объединить их все в pd.DataFrame, но хочу, чтобы каждая строка запоминала, из какого файла она пришла.

import pandas as pd
#Let's make our two fake csv files a and b:
with open('a.csv', mode='w') as a, open('b.csv', mode='w') as b:
     a.write('col1,col2\n1,1')
     b.write('col1,col2\n2,2')

csv_files = ['a.csv', 'b.csv']
dfs = [pd.read_csv(csv_file).assign(filename=csv_file) for csv_file in csv_files] 
#assign let's you assign the value of a column and returns a DataFrame, so it's 
#great for list comprehensions, in which the df['some_col']='some_var'
#syntax does not work

combined_ab = pd.concat(dfs)
combined_ab
#   col1  col2 filename
#0     1     1    a.csv
#0     2     2    b.csv
0 голосов
/ 29 мая 2018

Не уверен, что это лучший способ сделать это, но он работает:

In [56]: df_list = []
    ...: for i in locals():
    ...:     try:
    ...:         if type(locals()[i]) == pd.core.frame.DataFrame and not i.startswith('_'):
    ...:             df_list.append(i)            
    ...:     except KeyError:
    ...:         pass  

In [57]: df_list
Out[57]: ['df', 'df2']

In [58]: for d in df_list:
    ...:     locals()[d]['Variable'] = d

In [59]: df
Out[59]: 
         Year  Value Variable
0  1995-01-02  0.844       df
1  1995-01-03  0.845       df
2  1995-01-04  0.845       df
3  1995-01-05  0.843       df
4  1995-01-06  0.840       df
5  1995-01-09  0.844       df
6  1995-01-10  0.847       df
7  1995-01-11  0.851       df

In [60]: df2
Out[60]: 
         Year  Value Variable
0  2008-01-02  0.844      df2
1  2008-01-03  0.845      df2
2  2008-01-04  0.845      df2
3  2008-01-05  0.843      df2
4  2008-01-06  0.840      df2
5  2008-01-09  0.844      df2
6  2008-01-10  0.847      df2
7  2008-01-11  0.851      df2
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...