使用Python / Pandas匹配样本对年度数据
虽然这可能听起来像统计问题,但请耐心等待.
我在不同采样位置采集的水样中有几种钙浓度.每月,每年,每隔一年在一些车站对水进行重新采样. 我想用Lindsey和Rupert(http://pubs.usgs.gov/sir/2012/5049/)进行的Wilcoxon-Pratt符号秩检验来测量各组站点钙浓度的年度和年代际变化.为了进行测试,我想创建一对数据,这些数据以一年(时间差为365天)或尽可能接近该时间范围分隔.配对测量应该具有相同的月份,只是不同的年份.我每个站每月只需要一对.我不希望平均样本浓度相同的站点,月份和年份. 以下是我的数据示例: SampleLocation CalciumConc_mgL SampleDate 10/1/1947 0:00 USGS-09382000 66.0 10/15/1947 0:00 USGS-09382000 132.0 1/1/1948 0:00 USGS-09382000 130.0 1/15/1948 0:00 USGS-09382000 98.0 5/1/1948 0:00 USGS-09382000 82.0 5/15/1948 0:00 USGS-09382000 53.0 6/1/1948 0:00 USGS-09382000 142.0 9/1/1948 0:00 USGS-09382000 107.0 9/15/1948 0:00 USGS-09382000 59.0 10/1/1948 0:00 USGS-09382000 106.0 10/15/1948 0:00 USGS-09382000 102.0 5/15/1949 0:00 USGS-09382000 59.0 6/1/1949 0:00 USGS-09382000 50.0 6/15/1949 0:00 USGS-09382000 161.0 9/1/1949 0:00 USGS-09382000 82.0 9/15/1949 0:00 USGS-09382000 376.0 10/1/1949 0:00 USGS-09382000 210.0 10/15/1949 0:00 USGS-09382000 131.0 1/1/1950 0:00 USGS-09382000 132.0 ... ... ... 9/20/1947 0:00 USGS-09288500 59.0 9/20/1947 0:00 USGS-09288500 59.0 6/9/1948 0:00 USGS-09288500 51.0 6/9/1948 0:00 USGS-09288500 51.0 9/29/1948 0:00 USGS-09288500 51.0 9/29/1948 0:00 USGS-09288500 51.0 9/10/1949 0:00 USGS-09288500 40.0 5/19/1941 0:00 USGS-09295000 33.0 6/16/1941 0:00 USGS-09295000 3.4 5/11/1947 0:00 USGS-09295000 42.0 6/22/1947 0:00 USGS-09295000 32.0 9/20/1947 0:00 USGS-09295000 97.0 6/9/1948 0:00 USGS-09295000 37.0 9/29/1948 0:00 USGS-09295000 126.0 9/10/1949 0:00 USGS-09295000 93.0 [429 rows x 2 columns] 我想生成一个看起来像这样的Pandas数据帧: SampleLocation SampleDate1 CaConc1 SampleDate2 CaConc2 USGS-09382000 10/1/1947 0:00 66.0 10/1/1948 0:00 106.0 USGS-09382000 10/15/1947 0:00 132.0 10/15/1948 0:00 102.0 USGS-09382000 5/15/1948 0:00 53.0 5/15/1949 0:00 59.0 ... ... ... ... ... USGS-09288500 9/20/1947 0:00 59.0 9/29/1948 0:00 51.0 我相信可以使用Pandas中的多索引功能来解决这个问题.到目前为止,我已经查看了以下stackoverflow问题,以帮助匹配日期和使用索引进行操作: > How to get the closest single row after a specific datetime index using Python Pandas 我认为第二个链接使用取消堆栈的多索引非常接近,如果我愿意聚合,我可以执行此操作,但我试图避免这种情况. 该技术与其他想要分析具有季节性趋势的数据的人相关,例如比较当前或接近同一天的流量排放或累积降水或温度. 解决方法
这种方法有点乱,但我试图让它更加健壮,以解决丢失的数据.
首先,我们将删除数据中的重复项,然后将日期转换为Pandas时间戳: df = df.drop_duplicates() df.SampleDate = [pd.Timestamp(ts) for ts in df.SampleDate] 然后让我们安排你的DataFrame,以便它在一组唯一的日期上编入索引(列将是位置ID): df2 = df.pivot_table(values='CalciumConc_mgL',index='SampleDate',columns='SampleLocation').ffill() 我已经填写了这些值以使结果更加健壮.您可能希望限制可能向前填充的天数(例如.ffill(limit = 30)). 现在我们可以将此DataFrame转换365个日期: df2_lagged = df2.shift(365) 堆叠df2和df2_lagged的SampleLocation: df2 = pd.DataFrame(df2.stack('SampleLocation',dropna=False)) df2_lagged = df2_lagged.stack('SampleLocation',dropna=False) 现在将滞后数据合并到df2. DataFrames具有完全相同的结构,因此您只需复制值: df2['lagged_val'] = df2_lagged 最后,交换位置和日期并重命名列: result = df2.swaplevel(0,1) result.columns = ['CalciumConc_mgL','CalciumConc_mgL_lagged_12m'] 使用60天滞后的样本数据: >>> result result.tail(10) CalciumConc_mgL CalciumConc_mgL_lagged_12m SampleLocation SampleDate USGS-421548113205301 1950-01-01 59 59 USGS-422818113225801 1950-01-01 59 NaN USGS-423200113472601 1950-01-01 33 33 USGS-424006113355301 1950-01-01 62 54 USGS-424142113340901 1950-01-01 54 54 USGS-424348113242701 1950-01-01 40 NaN USGS-424431113412301 1950-01-01 46 NaN USGS-424511113291401 1950-01-01 38 38 USGS-424518113282002 1950-01-01 39 39 USGS-424659113433701 1950-01-01 39 39 并只是索引位置ID: result = result.reset_index().set_index('SampleLocation') >>> result.loc['USGS-09402500',:] CalciumConc_mgL CalciumConc_mgL_lagged_12m SampleDate 1941-05-18 NaN NaN 1941-05-19 NaN NaN 1941-06-16 NaN NaN 1941-10-01 102 NaN 1941-10-12 132 NaN 1941-10-21 119 NaN 1943-09-18 110 NaN 1943-10-01 138 NaN 1943-10-11 140 NaN 1943-10-12 140 NaN 1943-10-14 140 NaN 1943-10-21 156 NaN 1944-01-01 116 NaN 1944-01-11 126 NaN 1944-01-13 126 NaN 1944-01-21 133 NaN 1944-05-01 84 NaN 1944-05-11 84 NaN 1944-05-13 66 NaN 1944-05-15 66 NaN 1944-05-16 66 NaN 1944-05-21 57 NaN 1944-05-22 57 NaN 1944-06-01 58 NaN 1944-06-11 57 NaN 1944-06-21 57 NaN 1944-09-01 134 NaN 1944-09-11 122 NaN 1944-09-15 122 NaN 1944-09-18 122 NaN ... ... ... 1949-05-03 63 62 1949-05-11 63 62 1949-05-15 63 62 1949-05-21 57 62 1949-06-01 58 133 1949-06-09 58 128 1949-06-10 58 128 1949-06-11 74 128 1949-06-12 74 128 1949-06-13 74 124 1949-06-15 74 112 1949-06-21 67 123 1949-06-23 67 123 1949-06-30 67 123 1949-09-01 142 123 1949-09-09 142 123 1949-09-10 142 131 1949-09-11 140 106 1949-09-15 140 108 1949-09-21 146 108 1949-09-28 146 102 1949-10-01 156 102 1949-10-11 153 102 1949-10-13 153 68 1949-10-14 153 68 1949-10-15 153 63 1949-10-21 152 63 1949-10-27 152 63 1949-10-28 152 63 1950-01-01 128 60 (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |