转换数据框

时间:2018-08-31 07:05:53

标签: python pandas dataframe

我想使用以下逻辑以有效的方式转换数据帧:

对于数据框的每一列,我确定出现在该特定列中的唯一出现次数。假设对于第i列,存在n_i个唯一的此类事件。然后,为这些事件中的每一个分配具有n_i个分量的唯一列表,以使该列表在每个位置都具有零,除了与所选唯一事件对应的一个位置之外。通过对每一列执行此操作,我将通过列表列表来唯一标识数据框中的每个元素。为了说明我想要的东西,一个例子可能会更方便。

采用以下数据框:

data = { 'name': ['Alarm1','Alarm2','Alarm2','Alarm3','Alarm4'],
    'severity':[1,2,3,4,4],
    'domain':['RAN','TRX','RAN','RAN','TRX']}
df=pd.DataFrame(data, index = [1,2,3,4,5])

然后,我想将此数据帧转换为类似于输出的numpy数组:

[[1, 0, 0, 0], [1, 0, 0, 0], [1, 0]]
[[0, 1, 0, 0], [0, 1, 0, 0], [0, 1]]
[[0, 1, 0, 0], [0, 0, 1, 0], [1, 0]]
[[0, 0, 1, 0], [0, 0, 0, 1], [1, 0]]
[[0, 0, 0, 1], [0, 0, 0, 1], [0, 1]]

我用于上述转换的代码如下:

l0=[((df.name.unique()==df.iloc[0][0])*1).tolist(),((df.severity.unique()==df.iloc[0][1])*1).tolist()]
l0.append(((df.domain.unique()==df.iloc[0][2])*1).tolist())
l1=[((df.name.unique()==df.iloc[1][0])*1).tolist(),((df.severity.unique()==df.iloc[1][1])*1).tolist()]
l1.append(((df.domain.unique()==df.iloc[1][2])*1).tolist())
l2=[((df.name.unique()==df.iloc[2][0])*1).tolist(),((df.severity.unique()==df.iloc[2][1])*1).tolist()]
l2.append(((df.domain.unique()==df.iloc[2][2])*1).tolist())
l3=[((df.name.unique()==df.iloc[3][0])*1).tolist(),((df.severity.unique()==df.iloc[3][1])*1).tolist()]
l3.append(((df.domain.unique()==df.iloc[3][2])*1).tolist())
l4=[((df.name.unique()==df.iloc[4][0])*1).tolist(),((df.severity.unique()==df.iloc[4][1])*1).tolist()]
l4.append(((df.domain.unique()==df.iloc[4][2])*1).tolist())

此后,我只打印所有列表l0,..,l4以获得输出。当然,当我手动构建每个列表时,这效率很低。我想进行迭代以便一次构造所有这些对象,并且还对每个列表的数据框中的每个列的column.unique部分进行迭代。

如果有人可以提供帮助或建议,我将不胜感激。先感谢您!

2 个答案:

答案 0 :(得分:0)

我认为需要get_dummies处理字符串值,因此首先使用astype

df1 = pd.get_dummies(df.astype(str))
print (df1)
   name_Alarm1  name_Alarm2  name_Alarm3  name_Alarm4  severity_1  severity_2  \
1            1            0            0            0           1           0   
2            0            1            0            0           0           1   
3            0            1            0            0           0           0   
4            0            0            1            0           0           0   
5            0            0            0            1           0           0   

   severity_3  severity_4  domain_RAN  domain_TRX  
1           0           0           1           0  
2           0           0           0           1  
3           1           0           1           0  
4           0           1           1           0  
5           0           1           0           1  

然后,如果需要的列表使用groupby之前的第一个值使用_到元组列表:

L = list(zip(*[x.values.tolist() for _, x in df1.groupby(lambda x: x.split('_')[0], axis=1)]))
print (L)

[([1, 0], [1, 0, 0, 0], [1, 0, 0, 0]), 
 ([0, 1], [0, 1, 0, 0], [0, 1, 0, 0]), 
 ([1, 0], [0, 1, 0, 0], [0, 0, 1, 0]), 
 ([1, 0], [0, 0, 1, 0], [0, 0, 0, 1]), 
 ([0, 1], [0, 0, 0, 1], [0, 0, 0, 1])]

或在带有split的列中创建MultiIndex

df1.columns = df1.columns.str.split('_', expand=True)
print (df1)
    name                      severity          domain    
  Alarm1 Alarm2 Alarm3 Alarm4        1  2  3  4    RAN TRX
1      1      0      0      0        1  0  0  0      1   0
2      0      1      0      0        0  1  0  0      0   1
3      0      1      0      0        0  0  1  0      1   0
4      0      0      1      0        0  0  0  1      1   0
5      0      0      0      1        0  0  0  1      0   1
   Alarm1  Alarm2  Alarm3  Alarm4
1       1       0       0       0
2       0       1       0       0
3       0       1       0       0
4       0       0       1       0
5       0       0       0       1

因此可以在第一级选择DataFrame

print (df1['name'])
   Alarm1  Alarm2  Alarm3  Alarm4
1       1       0       0       0
2       0       1       0       0
3       0       1       0       0
4       0       0       1       0
5       0       0       0       1

print (df1['domain'])
   RAN  TRX
1    1    0
2    0    1
3    1    0
4    1    0
5    0    1

如有必要,请转换为numpy array

print (df1['name'].values)
[[1 0 0 0]
 [0 1 0 0]
 [0 1 0 0]
 [0 0 1 0]
 [0 0 0 1]]

print (df1['domain'].values)
[[1 0]
 [0 1]
 [1 0]
 [1 0]
 [0 1]]

答案 1 :(得分:0)

您可能需要pd.get_dummies

import pandas as pd

data = {
    'name': ['Alarm1','Alarm2','Alarm2','Alarm3','Alarm4'],
    'severity': [1,2,3,4,4],
    'domain': ['RAN','TRX','RAN','RAN','TRX']}

df = pd.DataFrame(data, index=[1,2,3,4,5])
df = df.astype(str)

df2 = pd.get_dummies(df)

out = list(zip(*[df2[[x for x in df2.columns if x.startswith(key)]].values.tolist() for key in data.keys()]))
print(out)

# Output
# [([1, 0, 0, 0], [1, 0, 0, 0], [1, 0]), 
#  ([0, 1, 0, 0], [0, 1, 0, 0], [0, 1]), 
#  ([0, 1, 0, 0], [0, 0, 1, 0], [1, 0]), 
#  ([0, 0, 1, 0], [0, 0, 0, 1], [1, 0]), 
#  ([0, 0, 0, 1], [0, 0, 0, 1], [0, 1])]
相关问题