我要收集许多天的数据,而不是每天都要填写,我可以选择说一天的数据实际上应该是另一天的重复。我想将现有数据框中的某些行重复到指定为重复的日子。我有一列指示当前日期是从哪一天开始重复,但我陷入了错误。

我已经找到了一种基于列值将行重复n次的方法,但是我尝试使用列作为索引来重复前行的数据。

我想使用“重复”列作为索引,将第一天的“数据”列中的部分复制到第三天的“数据”列中。我想在更多不同的日子里这样做。

data = [['1', 5,np.NaN], ['1',5,np.NaN],['1',5,np.NaN], ['2', 6,np.NaN],['2', 6,np.NaN],['2', 6,np.NaN], ['3',np.NaN,1], ['3',np.NaN,np.NaN],['3', np.NaN,np.NaN]]

df = pd.DataFrame(data, columns = ['Day', 'Data','repeat_tag'])

最佳答案

我稍微扩展了您的测试数据:

data = [['1', 51, np.nan], ['1', 52, np.nan],     ['1', 53, np.nan],
        ['2', 61, np.nan], ['2', 62, np.nan],     ['2', 63, np.nan],
        ['3', np.nan, 1],  ['3', np.nan, np.nan], ['3', np.nan, np.nan],
        ['4', np.nan, 2],  ['4', np.nan, np.nan], ['4', np.nan, np.nan]]
df = pd.DataFrame(data, columns = ['Day', 'Data', 'repeat_tag'])


细节:


有4天的观察时间。
每个观察值都有不同的值(数据)。
为避免“单日复制”,将复制第3天的值
第1天,从第2天开始的第4天。


我假设repeat_tag的非null值只能放在一个
观察“目标”日。

我还添加了obsNo列以标识特定日期的观察结果:

df['obsNo'] = df.groupby('Day').cumcount().add(1);


(稍后需要)。

实际处理的第一步是生成replDays表,其中Day
column是目标日期,repeat_tag是源日期:

replDays = df.query('repeat_tag.notnull()')[['Day', 'repeat_tag']]
replDays.repeat_tag = replDays.repeat_tag.astype(int).apply(str)


对repeat_tag列进行了一些类型操作。
由于此列包含NaN值且非null值是int,因此此列为
强制为float64。因此,要获取字符串类型(与Day相比)
必须转换:


首先是int,要删除小数部分。
然后到str。


结果是:

  Day repeat_tag
6   3          1
9   4          2


(用第1天的数据填充第3天的数据,用第2天的数据填充第4天的数据)。

下一步是生成replData表:

replData = pd.merge(replDays, df, left_on='repeat_tag', right_on='Day',
    suffixes=('_src', ''))[['Day_src', 'Day', 'Data', 'obsNo']]\
    .set_index(['Day_src', 'obsNo']).drop(columns='Day')


结果是:

               Data
Day_src obsNo
3       1      51.0
        2      52.0
        3      53.0
4       1      61.0
        2      62.0
        3      63.0


如你看到的:


替换数据只有一列-数据(从第1天和第2天开始)。
MutliIndex包含日期和观察号(两者均为
需要进行适当的更新)。


最后一部分包括以下步骤:


将df复制到res(结果),将索引设置为Day和obsNo
(需要更新)。
使用来自replData的数据更新此表。
将Day和obsNo从索引移回“常规”列。


代码是:

res = df.copy().set_index(['Day', 'obsNo'])
res.update(replData)
res.reset_index(inplace=True)


如果需要,还可以删除obsNo列。

关于彼得的解决方案的评论:
如果源数据在任何一天中都包含不同的值,那么他的代码将失败
与InvalidIndexError一起使用,可能是由于缺少
在特定日期内的个人观察。
这证实了我添加obsNo列的想法是有效的。

关于python - 根据列值重复数据框的各个部分,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/56716238/

10-13 07:22
查看更多