我有一个数据框,其中包含来自多个站点的年度数据。在每个站点内,有多个数据源,这些数据源的年数并不相等。我不知道提前几年的上下限,并且每个站点的上下限都不同。
我的数据如下:
Year Site Source Value
1880 1 A 1.2
1881 1 A 1.4
1882 1 A 2.1
1883 1 A 2.7
1881 1 B 1.3
1882 1 B 1.8
1883 1 B 1.4
1891 2 A 1.9
1892 2 A 2.0
1893 2 A 2.1
1892 2 B 2.4
1893 2 B 2.2
对于每个站点,我想使用时间跨度最短的源来裁剪数据,以便数据看起来像这样:
Year Site Source Value
1881 1 A 1.4
1882 1 A 2.1
1883 1 A 2.7
1881 1 B 1.3
1882 1 B 1.8
1883 1 B 1.4
1892 2 A 2.0
1893 2 A 2.1
1892 2 B 2.4
1893 2 B 2.2
到目前为止我的尝试:
for site in df['Site'].unique():
A = df[df['Source'] == 'A']
B = df[df['Source'] == 'B']
if len(A['Year']) < len(B['Year']):
B['Year'] = B.clip(A['Year'].min, A.['Year'].max)
if len(B['Year']) < len(A['Year'):
A['Year'] = A.clip(B['Year'].min, B['Year'].max)
df[df['Source'] == 'A'] = A
B = df[df['Source'] == 'B']
产生:
Year Site Source Value
1881 1 A 1.4
1882 1 A 2.1
1883 1 A 2.7
1881 1 B 1.3
1882 1 B 1.8
1883 1 B 1.4
1881 2 A 1.4
1882 2 A 2.1
1883 2 A 2.7
1881 2 B 1.3
1882 2 B 1.8
1883 2 B 1.4
答案 0 :(得分:1)
由于这些站点是独立的,因此可以在groupby中使用它们的功能,与您的外循环类似。
您可以编写一个处理每个站点的函数,删除超出重叠范围的行:
def filter_site(site):
# look at the lowest year for each source,
# take the max value of them as lower bound
lower = site.groupby("Source").Year.min().max()
# likewise for upper bound
upper = site.groupby("Source").Year.max().min()
# filter with lower and upper bound
return site[(site.Year >= lower) & (site.Year <= upper)]
然后在所有站点上应用该功能:
df.groupby("Site", group_keys=False).apply(filter_site)