1

I made a list of a set of dfs:

dflist = [df1, df2, df3, df4]

I want to loop through all the dfs in the list, print the df name, and print the first 2 lines.

In unix it is simple to do what I want:

cat dflist | while read i; do echo $i && head -2 $i; done

Which returns:

US_distribution_of_soybean_aphid_2022.csv
State,Status of Aphis glycines in 2022,Source,
Connecticut,Present,Rutledge (2004),

But in pandas,

for i in dflist:
    print('i')
    print(i.head(2))

returns literal i followed by the desired head(2) results.

i

   Year           Analyte            Class  SortOrder  PercentAcresTreated  \
0  1991          Methomyl        carbamate       2840              0.00125   
1  1991  Methyl parathion  organophosphate       2900              0.01000   

Using:

for i in dflist:
    print(i)

Prints each df in its entirety.

Very frustrating to a newbie trying to understand the python equivalents of commands I use every day. I'm currently working in a jupyter notebook, if that matters.

Sunderam Dubey
  • 1
  • 11
  • 20
  • 40
  • 1
    share the actual output and the expected out, that's unclear what you want. Also share how you built `dflist` – azro Aug 05 '22 at 20:56
  • @MichaelS. Yes! That worked, thank you! After doing df.name on each df, when I ran `for i in dflist: print(i.name) print(i.head(2))` I got the result I was after. **Thank you!** – Sara Oppenheim Aug 05 '22 at 21:01

2 Answers2

2

Before proceeding, give these answers a read. You can name your dataframes with df.name after you create them. Then you can print their names with print(df.name). Just be careful to not have a column named name. In reality, you can name name anything. df.dataframe_name works as well. Just make it unique in that it is not one of your column names:

test = pd.DataFrame({"Column":[1,2,3,4,5]})
test.name = "Test"

new_test = pd.DataFrame({"Column":[1,2,3,4,5]})
new_test.name = "New Test"

third_test = pd.DataFrame({"Column":[1,2,3,4,5]})
third_test.name = "Third Test"

last_test = pd.DataFrame({"Column":[1,2,3,4,5]})
last_test.name = "Last Test"
dflist = [test, new_test, third_test, last_test]
for i in dflist:
    print(i.name)
    print(i.head(2))

Output:

Test
   Column
0       1
1       2
New Test
   Column
0       1
1       2
Third Test
   Column
0       1
1       2
Last Test
   Column
0       1
1       2
Michael S.
  • 3,050
  • 4
  • 19
  • 34
  • You can assign anything in a DataFrame, but if you clash with a useful column or method you will have problems. Rather use `df.attrs` to store metadata. That said, for the use described by OP a simple dictionary seems more appropriate. – mozway Aug 05 '22 at 21:14
  • it seems counter to the ethos of coding that only ONE answer can be accepted when of course there are many equally valid ways to solve a problem... – Sara Oppenheim Aug 05 '22 at 23:04
1

You must use a container. Accessing names programmatically is highly discouraged.

For instance, a list:

dfs = [df1, df2, df3]

for df in dfs:
    print(df.head())

Or, if you need "names", a dictionary:

dfs = {'start': df1, 'middle': df2, 'end': df3}

for name, df in dfs.items():
    print(name)
    print(df.head())
mozway
  • 194,879
  • 13
  • 39
  • 75
  • are you saying this method is safer than doing df.names? Can you explain why? – Sara Oppenheim Aug 05 '22 at 21:31
  • @Sara I briefly mentioned it in my comment, this is unsafe as it can conflict with the DataFrame indexing. Try `df = pd.DataFrame({'name': [1,2,3]}) ; df.name = 'abc' ; print(df)`. You just corrupted the data and `df.name` won't even return a string. Even if it doesn't conflict it can be lost on certain operations that return a copy of the DataFrame. There is a [`attrs`](https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.DataFrame.attrs.html) dictionary to save metadata but the feature is experimental and might change in the future ;) – mozway Aug 06 '22 at 05:29
  • thank you for taking the time to lay that out. I'm trying to keep an eye on what's "under the hood" as I start using python and appreciate your explanation. – Sara Oppenheim Aug 06 '22 at 12:50