我想使用以下逻辑以有效的方式转换数据帧:
对于数据框的每一列,我确定出现在该特定列中的唯一出现次数。假设对于第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部分进行迭代。
如果有人可以提供帮助或建议,我将不胜感激。先感谢您!
答案 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])]