我有一个数据集,显示了从1970年到2013年100多个国家的年度增长指标。并非所有国家都有所有年份的数据,年份最少的国家有30年的数据。我想把事情搞清楚,让所有国家都给我看30年的数据,去掉那些超过30年的国家的数据。下面我举一个例子。你知道吗
我考虑过使用循环从数据框中删除数据,直到所有国家出现30次,然后构建一个全新的数据框,但我相信有更好的解决方案。你知道吗
import pandas as pd
data = {'Country':['Israel','Congo','Denmark',
'Israel','Denmark',
'Israel','Congo',
'Israel','Congo','Denmark'],
'Year':[2000,2000,2000,
2001,2001,
2002,2002,
2003,2003,2003],
'Value':[2.5,1.2,3.1,2.8,1.1,2.9,3.1,1.9,3.0,3.1]}
df = pd.DataFrame(data=data)
df
Country Year Value
0 Israel 2000 2.5
1 Congo 2000 1.2
2 Denmark 2000 3.1
3 Israel 2001 2.8
4 Denmark 2001 1.1
5 Israel 2002 2.9
6 Congo 2002 3.1
7 Israel 2003 1.9
8 Congo 2003 3.0
9 Denmark 2003 3.1
上面的代码创建了一个数据帧,示例仅使用3个国家和4年。从数据框中,你可以看到以色列有4年的数据,而丹麦和刚果只有3年。我想从以色列撤走一年,这样所有国家都有三年。在真实的数据框架中,我想从超过30年的国家中删除年份,以便所有国家都有相同的年份,最好删除值最小的年份。你知道吗
下面是我使用for循环的解决方案,它使用了大量代码行:
gp = df.groupby('Country').groups #Group by country name
d = {} #Build dictionary Country Name => index list.
for i in gp: #Iterate over all countries until a list of 3 indeces is
#reached for each country.
d[i] = []
for j in gp[i]:
if len(d[i])<3: #A country appears once every year in the dataset,
#3 means 3 years. If a country appears more than 3 times, it will only
#include the indices of the first 3 occurrences.
d[i].append(j)
indeces = [] #Gather the indeces to keep in the dataframe.
for i in d:
for j in d[i]:
if len(d[i])==3: #make sure the list has exactly 3 items
indeces.append(j)
final_df = df.loc[indeces,['Country','Year','Value']]
final_df
#Now I have one less value for Israel, so all countries have 3 values.
Country Year Value
1 Congo 2000 1.2
6 Congo 2002 3.1
8 Congo 2003 3.0
2 Denmark 2000 3.1
4 Denmark 2001 1.1
9 Denmark 2003 3.1
0 Israel 2000 2.5
3 Israel 2001 2.8
5 Israel 2002 2.9
这是我使用熊猫的解决方案。它做了它必须做的事情,即使它使用了很多行代码。感谢@Vaishali的帮助:
输出:
您可以从“年”列中的唯一值创建最近几年的列表,并使用布尔索引来使用该列表对数据帧进行索引。你知道吗
如果您的年份值不一定按顺序排列,请使用numpy unique,它返回一个排序数组,而不是pandas unique()
这里是另一个解决方案,每个国家返回最近3年。如果数据没有按年份排序,则需要先排序。你知道吗
如果数据没有排序,首先使用
相关问题 更多 >
编程相关推荐