在我之前的问题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过滤到上述条件之后,我希望能够使用过滤后的数据调用league
或BOS
。这样做对我来说很容易开发其他功能。
答案 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]