遍历数据框列表以删除特定的行Pandas

时间:2019-08-08 12:32:34

标签: python pandas

在我之前的问题where I asked to drop particular rows in Pandas

在帮助下,我要删除1980年之前的行。“季节”列(具有年份)的格式如下:

 2018-19
 2017-18
 This
 list would go
 till 1960

在前面的问题中,@ jezrael提供了一个解决方案,该解决方案帮助我在1980年之前删除行。

我有一个包含30个数据帧的列表(称为list)。我想遍历30个数据帧,并为每一个df删除1980年之前的所有行。例如,list中的一项是BOS 如果BOS['Season]具有:

 2018-19
 2017-18
 1959-1960

我应该得到

2018-19
2017-18

这样的结果应该适用于list

中的所有数据帧

这是我尝试过的方法,但出现错误或什么都不会发生:

for df in list:
   df = df[df['Season'].str.split('-').str[0].astype(int) > 1980]

我的代码有什么问题?我是python的新手。我认为通过将df分配给更改,它将对df

中的每个'list实施

谢谢!

更新: 我有一个名为list的{​​{1}}。该列表有30个数据框。我看了jazrael和IMCoin的解决方案。他们俩都工作了。但是这是我的要求。

在为每个DataFrame删除1980年之前的行之后。我希望能够直接使用该DataFrame,而不是通过列表使用。这就是我的意思。

league

这30个城市数据框已全部添加到列表 #Before Appending to the list BOS = pd.read_csv(dir+"Boston_Sheet") # I have 30 different cities, each having a CSV file and making each city have # their own DataFrame. So Boston as `BOS`, Chicago as `CHI` and like that 30 cities. 中。 在将城市DataFrame过滤到上述条件之后,我希望能够使用过滤后的数据调用leagueBOS。这样做对我来说很容易开发其他功能。

2 个答案:

答案 0 :(得分:1)

您需要创建过滤后的DataFrame的新列表或重新分配旧的列表:

注意:请勿使用变量list,因为builtins(Python代码字)。

L = [df[df['Season'].str.split('-').str[0].astype(int) > 1980] for df in L]

循环版本:

output = []
for df in L:
   df = df[df['Season'].str.split('-').str[0].astype(int) > 1980]
   output.append(df)

如果仅需要提取长度为4的前整数:

L = [df, df]
L = [df[df['Season'].str.extract('(\d{4})', expand=False).astype(float) > 1980] 
          for df in L]

print (L)
[    Season
0  2018-19
1  2017-18,     Season
0  2018-19
1  2017-18]

编辑:

如果数据具有相同的结构,我建议创建一个带有新列的大型DataFrame以区分城市:

import glob

files = glob.glob('files/*.csv')
dfs = [pd.read_csv(fp).assign(City=os.path.basename(fp).split('.')[0]) for fp in files]
df = pd.concat(dfs, ignore_index=True)
print (df)
          Season           City
0        2018-19   Boston_Sheet
1           This   Boston_Sheet
2  list would go   Boston_Sheet
3      till 1960   Boston_Sheet
4        2018-19  Chicago_Sheet
5        2017-18  Chicago_Sheet
6           This  Chicago_Sheet

df1 = df[df['Season'].str.extract('(\d{4})', expand=False).astype(float) > 1980]
print (df1)
     Season           City
0   2018-19   Boston_Sheet
4   2018-19  Chicago_Sheet
5   2017-18  Chicago_Sheet

df2 = df1[df1['City'] == 'Boston_Sheet']
print (df2)
    Season          City
0  2018-19  Boston_Sheet

df3 = df1[df1['City'] == 'Chicago_Sheet']
print (df3)
     Season           City
4   2018-19  Chicago_Sheet
5   2017-18  Chicago_Sheet

如果需要每个DataFrame分开,则可以通过DataFrames词典:

import glob

files = glob.glob('files/*.csv')
dfs_dict = {os.path.basename(fp).split('.')[0] : pd.read_csv(fp) for fp in files}

print (dfs_dict)

print (dfs_dict['Boston_Sheet'])
          Season
0        2018-19
1           This
2  list would go
3      till 1960

print (dfs_dict['Chicago_Sheet'])
0   2018-19
1   2017-18
2      This

然后在字典理解中进行处理:

dfs_dict = {k:v[v['Season'].str.extract('(\d{4})', expand=False).astype(float) > 1980] 
                 for k, v in dfs_dict.items()}
print (dfs_dict)
{'Boston_Sheet':     Season
0  2018-19, 'Chicago_Sheet':      Season
0   2018-19
1   2017-18}

print (dfs_dict['Boston_Sheet'])
    Season
0  2018-19

print (dfs_dict['Chicago_Sheet'])
     Season
0   2018-19
1   2017-18

答案 1 :(得分:1)

如果要就地修改列表:

for index in range(len(df_list)):
    df_list[index] = df_list[index].loc[df_list[index]['Season'].str.split('-').str[0].astype(int) > 1980]

当您遍历列表对象本身时,它会在每次迭代时创建一个新对象,并且每次旋转都会删除该对象。

如果要循环使用列表的长度,并通过索引访问数据,则将修改列表本身,而不是使用for some_copy_item in df_list制作的副本。


最小示例:

    arr = [1, 2, 3, 4, 5]
    print(arr) # [1, 2, 3, 4, 5]

    for number in arr:
        number += 1
    print(arr) # [1, 2, 3, 4, 5]

    for idx in range(len(arr)):
        arr[idx] += 1
    print(arr) # [2, 3, 4, 5, 6]