python范围从数据框生成额外的行

时间:2018-02-02 20:10:13

标签: python python-3.x list pandas numpy

我有一个看起来像这样的表:

mapping table

如何将其转换为:

UINT_MAX+1

这是为了使关系数据库之后更容易加入

2 个答案:

答案 0 :(得分:0)

这有点难以理解,但它将实现您的需求

df=pd.DataFrame({'ID':[10,20],'map':['A','C'],'Range':['001:004,212','001:007']})

df.Range=df.Range.str.split(',')
a=df.set_index(['ID','map']).Range.apply(pd.Series).stack()

yourdf=a.str.split(':').apply(pd.Series).ffill(1).\
   apply(lambda x : [np.arange(int(x[0]),int(x[1])+1)],1)[0].\
       apply(pd.Series).stack().\
          reset_index(level=[2,3],drop=True).reset_index() 

yourdf
Out[756]: 
    ID map      0
0   10   A    1.0
1   10   A    2.0
2   10   A    3.0
3   10   A    4.0
4   10   A  212.0
5   20   C    1.0
6   20   C    2.0
7   20   C    3.0
8   20   C    4.0
9   20   C    5.0
10  20   C    6.0
11  20   C    7.0

答案 1 :(得分:0)

一些vanilla python方法:

odf = pd.DataFrame([{'ID':'10', 'range':'001:004,212','mapping_value':'A'},
                    {'ID':'20', 'range':'001:007','mapping_value':'C'}])

df_input = []

def expand_range(i_range):
    lower, upper = i_range.split(':')
    return [str(e).zfill(3) for e in range(int(lower), int(upper)+1)]

for r in odf.itertuples():
    for rg in [element for sublist in
               [expand_range(e) if ':' in e else [e] for e in r.range.split(',')]
               for element in sublist]:
        df_input.append({'ID':r.ID,'mapping_value':r.mapping_value,'range':rg})

df = pd.DataFrame(df_input)

这给出了:

    ID mapping_value range
0   10             A   001
1   10             A   002
2   10             A   003
3   10             A   004
4   10             A   212
5   20             C   001
6   20             C   002
7   20             C   003
8   20             C   004
9   20             C   005
10  20             C   006
11  20             C   007

编辑: 从iterrows()切换到itertuples()因为它应该更快一点,通过返回namedtuples并显然保留dtypes来支持漂亮的点符号