104

How do I get the name of a DataFrame and print it as a string?

Example:

boston (var name assigned to a csv file)

import pandas as pd
boston = pd.read_csv('boston.csv')

print('The winner is team A based on the %s table.) % boston
jpp
  • 159,742
  • 34
  • 281
  • 339
leo
  • 1,565
  • 3
  • 11
  • 10
  • 1
    Do you mean variable name? – Anand S Kumar Jul 30 '15 at 15:03
  • 3
    It's worth reading [this](http://stackoverflow.com/questions/544919/can-i-print-original-variables-name-in-python) and [this](http://stackoverflow.com/questions/592746/how-can-you-print-a-variable-name-in-python), and the comments and links therein. – Matt Hall Jul 30 '15 at 15:07

7 Answers7

86

You can name the dataframe with the following, and then call the name wherever you like:

import pandas as pd
df = pd.DataFrame( data=np.ones([4,4]) )
df.name = 'Ones'

print df.name
>>>
Ones
starball
  • 20,030
  • 7
  • 43
  • 238
ajsp
  • 2,512
  • 22
  • 34
  • 3
    I need to have the name as a variable. import pandas as pd df = pd.DataFrame( data=np.ones([4,4]) ) df.name = 'df' print df.name >>> df – leo Jul 30 '15 at 16:19
  • 13
    For posterity, as of v 0.18.1 this does [not survive pickling](https://github.com/pandas-dev/pandas/issues/447#issuecomment-10949838) (for v 0.18.1 use `to_pickle`/ `read_pickle` instead of `save`/`load` if trying to reproduce the GitHub comment). – tmthydvnprt Jan 05 '17 at 16:28
  • 7
    A workaround I found is to place your `DataFrame`'s name in the index's name attribute (e.g. `df.index.name = 'Ones'`). This is maintained during pickling. This only works if your `DataFrame`'s index is not already named something useful... – tmthydvnprt Jan 05 '17 at 16:33
  • 1
    FYI, this was found while using `DataFrame`s inside `multiprocessing.Pool()` workers. The attributes were not maintained during `.map()` because of the pickling it uses. – tmthydvnprt Jan 05 '17 at 16:50
  • 13
    This is a poor idea because if you as much as `drop` something, the returned object will no longer have a `name` attribute. It's tempting, but will create inexplicable errors down the line. – sapo_cosmico Aug 01 '18 at 15:06
  • 10
    Really veru bad idea. If you call df.name = Ones is the same than df['name] = 'Ones'. it means the valiues for that column will be 'One'. SO it is not a correct answer. You can stor your dataframes within a dictionary and use the key to identify them –  Apr 01 '19 at 15:01
  • @user2270655 that's only the case if you already have a column named 'Ones'. If there is no column names 'Ones' the dot notation won't create a new column. – ajsp Jul 22 '22 at 09:36
54

Sometimes df.name doesn't work.

you might get an error message:

'DataFrame' object has no attribute 'name'

try the below function:

def get_df_name(df):
    name =[x for x in globals() if globals()[x] is df][0]
    return name
otmezger
  • 10,410
  • 21
  • 64
  • 90
Min
  • 581
  • 4
  • 2
  • 5
    It will throw ` 'DataFrame' object has no attribute 'name'` when it doesn't assign any name – Mohamed Thasin ah Nov 20 '18 at 07:33
  • 6
    Just to make sure people aren't confused: what the snippet here does is to find the dataframe in all currently defined global variables and return its variable name. This is **NOT** guaranteed to work (e.g. your DF is a local variable) and there are no error handling mechanisms in place. You should only use this if you're sure what you're doing! – Zecong Hu Dec 08 '20 at 15:43
  • chill dude. Its only a suggestion for a solution. However, I have this situation where this snippet of code is not working. – GenDemo Apr 03 '23 at 23:10
30

In many situations, a custom attribute attached to a pd.DataFrame object is not necessary. In addition, note that pandas-object attributes may not serialize. So pickling will lose this data.

Instead, consider creating a dictionary with appropriately named keys and access the dataframe via dfs['some_label'].

df = pd.DataFrame()

dfs = {'some_label': df}
jpp
  • 159,742
  • 34
  • 281
  • 339
17

DataFrames don't have names, but you have an (experimental) attribute dictionary you can use. For example:

df.attrs['name'] = "My name"   # Can be retrieved later

attributes are retained through some operations.

creanion
  • 2,319
  • 2
  • 13
  • 17
  • Using `df.attrs['name']` after pickling works. Great answer. – Leonardo Jul 08 '22 at 21:21
  • Thank you for alerting everyone about this new feature. The attributes dictionaries in series.attrs and dataframe.attrs both work and can contain as many attributes as one wishes to bind in the attributes dictionary. – Rich Lysakowski PhD Jul 27 '22 at 05:41
  • 1
    my pleasure. As noted, pandas says this is an “experimental” feature, so hopefully they won't change it too much or remove it. – creanion Aug 23 '22 at 17:54
15

From here what I understand DataFrames are:

DataFrame is a 2-dimensional labeled data structure with columns of potentially different types. You can think of it like a spreadsheet or SQL table, or a dict of Series objects.

And Series are:

Series is a one-dimensional labeled array capable of holding any data type (integers, strings, floating point numbers, Python objects, etc.).

Series have a name attribute which can be accessed like so:

 In [27]: s = pd.Series(np.random.randn(5), name='something')

 In [28]: s
 Out[28]: 
 0    0.541
 1   -1.175
 2    0.129
 3    0.043
 4   -0.429
 Name: something, dtype: float64

 In [29]: s.name
 Out[29]: 'something'

EDIT: Based on OP's comments, I think OP was looking for something like:

 >>> df = pd.DataFrame(...)
 >>> df.name = 'df' # making a custom attribute that DataFrame doesn't intrinsically have
 >>> print(df.name)
 'df'
dhuang
  • 909
  • 4
  • 18
2

I am working on a module for feature analysis and I had the same need as yours, as I would like to generate a report with the name of the pandas.Dataframe being analyzed. To solve this, I used the same solution presented by @scohe001 and @LeopardShark, originally in https://stackoverflow.com/a/18425523/8508275, implemented with the inspect library:

import inspect

def aux_retrieve_name(var):
    callers_local_vars = inspect.currentframe().f_back.f_back.f_locals.items()
    return [var_name for var_name, var_val in callers_local_vars if var_val is var]

Note the additional .f_back term since I intend to call it from another function:

def header_generator(df):
    print('--------- Feature Analyzer ----------')
    print('Dataframe name: "{}"'.format(aux_retrieve_name(df)))
    print('Memory usage: {:03.2f} MB'.format(df.memory_usage(deep=True).sum() / 1024 ** 2))
    return

Running this code with a given dataframe, I get the following output:

header_generator(trial_dataframe)

--------- Feature Analyzer ----------
Dataframe name: "trial_dataframe"
Memory usage: 63.08 MB

tbnsilveira
  • 468
  • 3
  • 8
1

Here is a sample function: 'df.name = file` : Sixth line in the code below

def df_list():
    filename_list = current_stage_files(PATH)
    df_list = []
    for file in filename_list:
        df = pd.read_csv(PATH+file)
        df.name = file
        df_list.append(df)
    return df_list
dcurrie27
  • 319
  • 3
  • 14
Arjjun
  • 1,203
  • 16
  • 15