我有这样的数据
import pandas as pd
test = pd.DataFrame(data={"IDX": [0,0,0,1,1,2],
"VAL": [27,5,13,27,24,13]})
IDX VAL
0 0 27
1 0 5
2 0 13
3 1 27
4 1 24
5 2 13并且希望扩展它,以便IDX成为列,VAL成为行名,而实际值只是指示值是否不存在/存在的指标,如下所示:
out = pd.DataFrame(data={"0": [1, 1, 0, 1],
"1": [0, 0, 1, 1],
"2": [0, 1, 0, 0]}, index=[5, 13, 24, 27])
0 1 2
5 1 0 0
13 1 0 1
24 0 1 0
27 1 1 0有没有办法在没有for-循环的情况下有效地做到这一点呢?
发布于 2018-10-15 11:31:11
将get_dummies与max结合使用
df = pd.get_dummies(test.set_index('VAL')['IDX'].sort_index()).max(level=0)
print (df)
0 1 2
VAL
5 1 0 0
13 1 0 1
24 0 1 0
27 1 1 0另一种解决方案--按组创建列表,然后使用MultiLabelBinarizer
s = test.groupby('VAL')['IDX'].apply(list)
print (s)
VAL
5 [0]
13 [0, 2]
24 [1]
27 [0, 1]
Name: IDX, dtype: object
from sklearn.preprocessing import MultiLabelBinarizer
mlb = MultiLabelBinarizer()
df = pd.DataFrame(mlb.fit_transform(s),columns=mlb.classes_, index=s.index)
print (df)
0 1 2
VAL
5 1 0 0
13 1 0 1
24 0 1 0
27 1 1 0发布于 2018-10-15 11:42:30
编辑:使用get_dummies。见@jezrael的回答。更正了我在下面使用的crosstabs。
pd.crosstab会完成这个任务(如果我们稍微修改一下的话)
pd.crosstab(index=test['VAL'], columns=test['IDX'])
IDX 0 1 2
VAL
5 1 0 0
13 1 0 1
24 0 1 0
27 1 1 0由于crosstab对值进行计数,并且不创建像get_dummies这样的指示符,如果我们想使用crosstabs,那么我们必须选择0以上的所有值,并将它们赋值给1。
In [76]: test = pd.DataFrame(data={"IDX": [0,0,0,0,0,1,1,2],
...: "VAL": [27,27,27,5,13,27,24,13]})
...:
...:
...:
In [77]: pd.crosstab(index=test['VAL'], columns=test['IDX'])
Out[77]:
IDX 0 1 2
VAL
5 1 0 0
13 1 0 1
24 0 1 0
27 3 1 0 <----------- IDX 0 VAL 27 = 3
In [78]: cross_tab = _
In [79]: cross_tab[cross_tab > 0] = 1
In [80]: cross_tab
Out[80]:
IDX 0 1 2
VAL
5 1 0 0
13 1 0 1
24 0 1 0
27 1 1 0 <---------- Back to a 1https://stackoverflow.com/questions/52815779
复制相似问题