如何基于Id重新构造数据集,忽略空列表和空列表

2024-06-28 20:37:31 发布

您现在位置:Python中文网/ 问答频道 /正文

如何根据列ID重新构造数据集

   id   time    A   B   C   D
A   11111   []  []  []  None
A   22222   [aaaa]  None    []  []
A   33333   []  []  [ccccc] sasasasasa
A   44444   None    None    []  ddfdfdf
A   55555   []  []  []  []
A   66666   []  [aaaa]  []  None
A   77777   [a1a1a1]    []  None    []
A   88888   None    []  []  None
A   99999   []  []  None    ssdskd
A   100000  []  []  []  sdsdsd
A   101111  None    [a1a1a1]    []  []
B   120000  [xxxx]  []  None    []
B   333333  []  None    []  []
B   130000      None    None    []
B   443430  []  []  [zzzz]  []
B   543434  none    [xxxx]  None    None

根据时间列,我们可以按如下方式重新排列数据集

 ID data A  data B  A   B   c   D
A   22222   44444   aaaa    aaaa    ccccc   sasasasasa,ddfdfdf
A   55555   77777   a1a1a1  a1a1a1  nan ssdskd , sdsdsd
B   120000  130000  xxxx    xxxx    zzzz    nan

这里data A列是column A出现的时间,data B列是column B出现的时间Column C将始终出现在AB之间

代码:

df1 = (df.set_index('id')
         .applymap(lambda x: np.nan if x == [] else x)
         .stack()
         .unstack()
         .apply(lambda x: x.str[0])
       )

Tags: 数据noneiddata时间nanaaaaxxxx
1条回答
网友
1楼 · 发布于 2024-06-28 20:37:31

第一部分解决方案类似-由两列创建MultiIndex,将空列表替换为缺少的值,由^{}重塑,通过索引将元素列表删除为标量,并将MultiIndex的时间级别转换为列:

df1 = (df.set_index(['id','time'])
         .applymap(lambda x: np.nan if x == [] else x)
         .stack()
         .str[0]
         .reset_index(level=1, name='new')
       )
print (df1)
        time     new
id                  
A  A   22222    aaaa
   C   33333   ccccc
   B   44444    aaaa
   A   55555  a1a1a1
   B   77777  a1a1a1
B  A  120000    xxxx
   C  333333    zzzz
   B  130000    xxxx

然后通过^{}重塑,只需要通过^{}新级别的重复数据消除MultiIndex,然后通过join展平列,以避免MultiIndex in columns

df1 = (df1.set_index(df1.groupby(level=[0,1]).cumcount(), append=True)
          .unstack(1)
          .reset_index(level=1, drop=True)
          .rename(columns={'time':'data'}, level=0))
df1.columns = df1.columns.map('_'.join)
df1 = df1.reset_index()
print (df1)
  id    data_A    data_B    data_C   new_A   new_B  new_C
0  A   22222.0   44444.0   33333.0    aaaa    aaaa  ccccc
1  A   55555.0   77777.0       NaN  a1a1a1  a1a1a1    NaN
2  B  120000.0  130000.0  333333.0    xxxx    xxxx   zzzz

编辑:首先使用聚合修改解决方案,如果连续值重复,则在列D中使用join进行修改,但数据中似乎存在错误,因为从time列创建的data列不匹配:

df1 = (df.set_index(['id','time'])
         .applymap(lambda x: np.nan if x == [] else x)
         .stack()
         .astype(str)
         .str.strip("[']")
         .reset_index(name='new')
         .rename(columns={'level_2':'cols'})
       )
df1['g'] = df1['cols'].ne(df1.groupby('id')['cols'].shift()).cumsum()
df1 = (df1.groupby(['id','cols', 'g'])
          .agg({'time':'first', 'new': ', '.join})
          .reset_index(level=2, drop=True))
print (df1)
           time                  new
id cols                             
A  A      22222                 aaaa
   A      77777               a1a1a1
   B      66666                 aaaa
   B     101111               a1a1a1
   C      33333                ccccc
   D      33333  sasasasasa, ddfdfdf
   D      99999       ssdskd, sdsdsd
B  A     120000                 xxxx
   B     543434                 xxxx
   C     443430                 zzzz

df1 = (df1.set_index(df1.groupby(level=[0,1]).cumcount(), append=True)
          .unstack(1)
          .reset_index(level=1, drop=True)
          .rename(columns={'time':'data'}, level=0))
df1.columns = df1.columns.map('_'.join)
df1 = df1.reset_index()
print (df1)
  id    data_A    data_B    data_C   data_D   new_A   new_B  new_C  \
0  A   22222.0   66666.0   33333.0  33333.0    aaaa    aaaa  ccccc   
1  A   77777.0  101111.0       NaN  99999.0  a1a1a1  a1a1a1    NaN   
2  B  120000.0  543434.0  443430.0      NaN    xxxx    xxxx   zzzz   

                 new_D  
0  sasasasasa, ddfdfdf  
1       ssdskd, sdsdsd  
2                  NaN 

相关问题 更多 >