[英]Create a new column filled by a variable name in python
假設我有一個數據框:
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
不知道這是否是最好的方法,但是它可以工作:
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
要獲取變量的名稱,我們可以使用以下答案中的代碼,復制如下:
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中的工作方式有關。 變量指向對象,即內存中的位置,但內存中的位置不指向后。 這意味着給定一個對象,您無法真正確定其名稱。 對於像列表這樣的容器也是如此。 例如,如果您有一個包含兩個對象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)
但是,如果您的DataFrame實際上都具有不同的數據源,那么有一種更簡便的方法來完成所有這些工作。 我經常遇到這樣的問題,即數據來自多個不同的來源,它們的名稱例如是文件名。 假設我有幾個.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
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.