为每个熊猫数据框ID替换一列中序列的缺失值

时间:2018-08-22 03:33:50

标签: python pandas dictionary dataframe padding

我有一个数据集:

dt = {'id': [120,120,120,120,120,121,121,345], 'day': [0, 1,2,3,4,0,2,0], 'value': [[0.3,-0.5,-0.7],[0.5,3.4,2.7],[0.45,3.4,0.7],[0.25,0.4,0.7],[0.15,0.34,0.17],[0.35,3.4,2.7],[0.5,3.44,2.57],[0.5,0.34,0.37]]}

df = pd.DataFrame(data=dt)


    day id  value
0   0   120 [0.3, -0.5, -0.7]
1   1   120 [0.5, 3.4, 2.7]
2   2   120 [0.45, 3.4, 0.7]
3   3   120 [0.25, 0.4, 0.7]
4   4   120 [0.15, 0.34, 0.17]
5   0   121 [0.35, 3.4, 2.7]
6   2   121 [0.5, 3.44, 2.57]
7   0   345 [0.5, 0.34, 0.37]

对于每个ID,应该有一个从0-5天的序列。在我的列ID数据集中,缺少了几天。我想为这些ID添加缺少的天数,并为相应的“值”列添加零数组。

结果:

   day  id  value
0   0   120 [0.3, -0.5, -0.7]
1   1   120 [0.5, 3.4, 2.7]
2   2   120 [0.45, 3.4, 0.7]
3   3   120 [0.25, 0.4, 0.7]
4   4   120 [0.15, 0.34, 0.17]
5   0   121 [0.35, 3.4, 2.7]
6   1   121 [0, 0, 0]
7   2   121 [0.5, 3.44, 2.57]
8   3   121 [0, 0, 0]
9   4   121 [0, 0, 0]
10  0   345 [0.5, 0.34, 0.37]
11  1   345 [0, 0, 0]
12  2   345 [0, 0, 0]
13  3   345 [0, 0, 0]
14  4   345 [0, 0, 0]

这是示例空间。我将在庞大的数据集上进行此操作。

我的尝试:

    r1=0
for i in df.id.unique():
    val=df.loc[df['id'] == i]
    mx=val.loc[val['day'].idxmax()].day
    for index,row in val.iterrows():
        if row.day!=r1:
            for k in range(int(row.day)-r1-1):
                a.append(np.asarray([0]*3))
            r1=row.day
        else:
            a.append(row.value)

        if(row.day==mx):
            a.append(row.value)
            for j in range(4-mx):
                a.append(np.asarray([0]*3)))
    r1=r1+1

但是此代码不起作用。

我该怎么做?

3 个答案:

答案 0 :(得分:1)

使用pd.MultiIndex.from_product

idx = pd.MultiIndex.from_product([df.id.unique(), np.arange(5)], names=['id', 'day'])

out = (df.set_index(['id', 'day'])
        .reindex(idx).reset_index()
)

然后只需将NaN替换为所需的填充值即可。

out.value = [d if isinstance(d, list) else [0, 0, 0] for d in out.value]

     id  day               value
0   120    0   [0.3, -0.5, -0.7]
1   120    1     [0.5, 3.4, 2.7]
2   120    2    [0.45, 3.4, 0.7]
3   120    3    [0.25, 0.4, 0.7]
4   120    4  [0.15, 0.34, 0.17]
5   121    0    [0.35, 3.4, 2.7]
6   121    1           [0, 0, 0]
7   121    2   [0.5, 3.44, 2.57]
8   121    3           [0, 0, 0]
9   121    4           [0, 0, 0]
10  345    0   [0.5, 0.34, 0.37]
11  345    1           [0, 0, 0]
12  345    2           [0, 0, 0]
13  345    3           [0, 0, 0]
14  345    4           [0, 0, 0]

答案 1 :(得分:1)

我假设每天(0到4)在您数据框中的某处至少被提及一次。

使id和日期成为MultiIndex(.add-to-cart-button-inner a:not(.custom-selector-here) { background: red; } ),然后将数据帧转换为表(set_index)。将会缺少值(某些ID缺少日期),请将它们设置为零(unstack)。然后将表转换回向量(fillna),并将索引转换回列(stack)。

reset_index

必须将数据框转换为类型df1 = df.set_index(['id', 'day']).unstack().fillna(0)\ .stack().reset_index().astype(object) ,否则无法将列表分配给列。现在,将0替换为您选择的列表:

object

请注意,您应该分配一个包含所需列表的单元素列表。

答案 2 :(得分:1)

这是使用pandas.concat

的一种方法
silly = pd.DataFrame(dict(day=range(5)))
dilly = pd.concat([
    d.merge(silly.assign(id=n), 'outer')
    for n, d in df.groupby('id')
], ignore_index=True)
willy = pd.Series([[0, 0, 0]] * len(dilly), dilly.index)
dilly.value.fillna(willy, inplace=True)

dilly

    day   id               value
0     0  120   [0.3, -0.5, -0.7]
1     1  120     [0.5, 3.4, 2.7]
2     2  120    [0.45, 3.4, 0.7]
3     3  120    [0.25, 0.4, 0.7]
4     4  120  [0.15, 0.34, 0.17]
5     0  121    [0.35, 3.4, 2.7]
6     2  121   [0.5, 3.44, 2.57]
7     1  121           [0, 0, 0]
8     3  121           [0, 0, 0]
9     4  121           [0, 0, 0]
10    0  345   [0.5, 0.34, 0.37]
11    1  345           [0, 0, 0]
12    2  345           [0, 0, 0]
13    3  345           [0, 0, 0]
14    4  345           [0, 0, 0]

使用pd.DataFrameunstack

pd.DataFrame(df.value.tolist(), [df.id, df.day]).unstack(fill_value=0).stack().pipe(
    lambda d: pd.Series(d.values.tolist(), d.index)
).reset_index(name='value')

     id  day               value
0   120    0   [0.3, -0.5, -0.7]
1   120    1     [0.5, 3.4, 2.7]
2   120    2    [0.45, 3.4, 0.7]
3   120    3    [0.25, 0.4, 0.7]
4   120    4  [0.15, 0.34, 0.17]
5   121    0    [0.35, 3.4, 2.7]
6   121    1     [0.0, 0.0, 0.0]
7   121    2   [0.5, 3.44, 2.57]
8   121    3     [0.0, 0.0, 0.0]
9   121    4     [0.0, 0.0, 0.0]
10  345    0   [0.5, 0.34, 0.37]
11  345    1     [0.0, 0.0, 0.0]
12  345    2     [0.0, 0.0, 0.0]
13  345    3     [0.0, 0.0, 0.0]
14  345    4     [0.0, 0.0, 0.0]