1

I am working with multiple dataframes in pandas, and am looking to only select certain columns from each of them.

AUD = [AUD2yr,AUD5yr,AUD10yr,AUD30yr]

for df in AUD:
    df = df[['Date','Open']]

I would ideally like to keep the names of the dataframes, but i receive the following error:

'NoneType' object is not subscriptable

Any help would be much appreciated.

1 Answer 1

1

'NoneType' object is not subscriptable

This means in your program somewhere None[...] is attempted. From the snippet you shared, that happens with df[...], i.e., somehow df became None.

Apart from that, doing df = df[["Date", "Open"]] inside the loop body will not alter the frames in the list; rather, it makes df now "look" at a new frame; the reference to the frame in the list is lost.

To fix that, you can traverse the list along with the index and modify with indexing:

for idx, frame in enumerate(AUD):
    AUD[idx] = frame[["Date", "Open"]]

or perhaps better, with a list comprehension:

AUD = [frame[["Date", "Open"]] for frame in AUD]

Lastly, to avoid the infamous SettingWithCopyWarning in case you further modify the frames, it's better you put .copy() after subsetting, e.g.,

AUD = [frame[["Date", "Open"]].copy() for frame in AUD]

Additionally, to affect the individual variables inside the list, i.e., AUD*yr vars in AUD = [AUD2yr, AUD5yr, AUD10yr, AUD30yr], there are some ways:

  • We can go for inplace=True option in operations we do. Note that this is not always possible; but in your specific case, we'll use .drop method which supports this, and we will drop all but "Date" and "Open" columns, so here we go:
for idx, frame in AUD:
    cols_to_drop = frame.columns.difference(["Date", "Open"])
    AUD[idx].drop(columns=cols_to_drop, inplace=True)

^this approach is infeasible with a list comprehension. But that brings us to 2nd option:

  • If there is handful of frames in the list, like you have 4 in AUD, we can unpack the new list again to those variables:
AUD2yr, AUD5yr, AUD10yr, AUD30yr = AUD = [frame[["Date", "Open"]].copy()
                                          for frame in AUD]

This will now not only alter AUD but also the individual variables. First option also does that, so your choice :)

  • There's a 3rd alternative... But that requires you to change AUD to be a dictionary rather than a list. This way you won't refer to the frames as bareword variables like AUD10yr but rather as dictionary keys, e.g., AUD["AUD10yr"]. For what it's worth, this might be a better practice if you got a lot frames especially. So,
# initialize as dictionary
AUD = {"AUD2yr": AUD2yr, "AUD5yr": AUD5yr, "AUD10yr": AUD10yr, "AUD30yr": AUD30yr}

# modify via dict comprehension, akin to list comprehension in the very above
AUD = {frame_name: frame[["Date", "Open"]].copy()
       for frame_name, frame in AUD.items()}

# now, can refer to individuals as:
print(AUD["AUD5yr"])

Some references:

Sign up to request clarification or add additional context in comments.

2 Comments

Thank you for the answer, however trying all of the methods above I am not able to call on each dataframe individually. In your examples, by printing AUD, it prints the dataframes as requested, but I cant print the individual dataframe. So when I print AUD2yr, it will still print all of the columns and not just the "Date" and "Open" column. Is there any way that I can get this from the AUD list? Thanks again
hi @Jack, I see what you mean (hopefully...) and presented 2 and a half ways to achieve that, I hope it helps (it starts at "Additionally" part)

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.