使用Pandas

时间:2018-02-13 23:45:27

标签: pandas variables pivot

我有一个遗留数据文件,其中包含以下格式的数据:

SURVEY  NUM TEMPORAL
WHS 1   Byz
WHS 1   Byz_Um
WHS 1   IAII
WHS 1   L_Isl
WHS 1   L_Rom
WHS 1   Mod
WHS 1   Nab
WHS 2   Byz
WHS 2   Mod
WHS 2   Unk
WHS 2   MP
WHS 3   Byz
WHS 3   Nab
WHS 3   LMP
WHS 3   UP
WHS 4   LMP
WHS 4   MP
WHS 4   UP
WHS 5   Byz
WHS 5   Unk
WHS 5   LMP

等。

基本上,列" NUM"是一个与特定网站相关的唯一标识符,以及" TEMPORAL"是与该网站相关联的值。无论出于何种原因,对于具有多种时间职业的站点(这个考古数据),原始文件在几行中重复这一点。我想用Pandas把它转换成这样的东西:

SURVEY NUM  Byz Byz_Um IAII L_Isl LMP L_Rom Nab MP Mod Unk UP
WHS 1   1  1  1  1  1  0  0  0  0  0  1  0  0  0
WHS 2   1  0  0  0  0  0  0  0  0  1  1  0  0  1
WHS 3   1  0  0  0  0  0  0  0  1  1  1  0  1  0
WHS 4   0  0  0  0  0  0  0  0  0  0  0  1  0  1
WHS 5   1  0  0  0  0  0  0  1  0  0  0  0  1  0

如果存在TEMPORAL期间,则将1放入新列。我尝试使用df.pivot和#34; NUM"作为索引和" TEMPORAL"作为列,但这不起作用。此数据库中有数千个站点,因此不可能手动执行此操作。有什么想法吗?

3 个答案:

答案 0 :(得分:2)

np.bincountpd.factorize

i, r = pd.factorize(df['SURVEY'])
j, c = pd.factorize(df['NUM TEMPORAL'])
n, m = len(r), len(c)

b = np.bincount(i * m + j, minlength=n * m).reshape(n, m)

pd.DataFrame(b, r, c)

       Byz  Byz_Um  IAII  L_Isl  L_Rom  Mod  Nab  Unk  MP  LMP  UP
WHS 1    1       1     1      1      1    1    1    0   0    0   0
WHS 2    1       0     0      0      0    1    0    1   1    0   0
WHS 3    1       0     0      0      0    0    1    0   0    1   1
WHS 4    0       0     0      0      0    0    0    0   1    1   1
WHS 5    1       0     0      0      0    0    0    1   0    1   0

pd.get_dummiespd.DataFrame.dot

pd.get_dummies(df['SURVEY']).T.dot(pd.get_dummies(df['NUM TEMPORAL']))

       Byz  Byz_Um  IAII  LMP  L_Isl  L_Rom  MP  Mod  Nab  UP  Unk
WHS 1    1       1     1    0      1      1   0    1    1   0    0
WHS 2    1       0     0    0      0      0   1    1    0   0    1
WHS 3    1       0     0    1      0      0   0    0    1   1    0
WHS 4    0       0     0    1      0      0   1    0    0   1    0
WHS 5    1       0     0    1      0      0   0    0    0   0    1

pd.crosstab

pd.crosstab(*df.values.T)

col_0  Byz  Byz_Um  IAII  LMP  L_Isl  L_Rom  MP  Mod  Nab  UP  Unk
row_0                                                             
WHS 1    1       1     1    0      1      1   0    1    1   0    0
WHS 2    1       0     0    0      0      0   1    1    0   0    1
WHS 3    1       0     0    1      0      0   0    0    1   1    0
WHS 4    0       0     0    1      0      0   1    0    0   1    0
WHS 5    1       0     0    1      0      0   0    0    0   0    1

或者

pd.crosstab(df['SURVEY'], df['NUM TEMPORAL'])

NUM TEMPORAL  Byz  Byz_Um  IAII  LMP  L_Isl  L_Rom  MP  Mod  Nab  UP  Unk
SURVEY                                                                   
WHS 1           1       1     1    0      1      1   0    1    1   0    0
WHS 2           1       0     0    0      0      0   1    1    0   0    1
WHS 3           1       0     0    1      0      0   0    0    1   1    0
WHS 4           0       0     0    1      0      0   1    0    0   1    0
WHS 5           1       0     0    1      0      0   0    0    0   0    1

reconstruction

pd.Series(1, df.values.T.tolist()).unstack(fill_value=0)

       Byz  Byz_Um  IAII  LMP  L_Isl  L_Rom  MP  Mod  Nab  UP  Unk
WHS 1    1       1     1    0      1      1   0    1    1   0    0
WHS 2    1       0     0    0      0      0   1    1    0   0    1
WHS 3    1       0     0    1      0      0   0    0    1   1    0
WHS 4    0       0     0    1      0      0   1    0    0   1    0
WHS 5    1       0     0    1      0      0   0    0    0   0    1

解释

  • df.values.T.tolist()传递长度为2的列表,包含两个级别。这些级别被解释为MultiIndex。
  • 1成为默认值。
  • {li> unstack fill_value=0相应地重塑

答案 1 :(得分:2)

使用get_dummies

df.set_index(['SURVEY','NUM']).TEMPORAL.str.get_dummies().sum(level=1)
Out[127]: 
     Byz  Byz_Um  IAII  LMP  L_Isl  L_Rom  MP  Mod  Nab  UP  Unk
NUM                                                             
1      1       1     1    0      1      1   0    1    1   0    0
2      1       0     0    0      0      0   1    1    0   0    1
3      1       0     0    1      0      0   0    0    1   1    0
4      0       0     0    1      0      0   1    0    0   1    0
5      1       0     0    1      0      0   0    0    0   0    1

答案 2 :(得分:0)

感谢piRSquared引导我找到正确的答案。以下代码完全符合我的要求:

df2 = pandas.crosstab(df['NUM'], [df['SURVEY'], df['TEMPORAL']])