我有一个遗留数据文件,其中包含以下格式的数据:
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"作为列,但这不起作用。此数据库中有数千个站点,因此不可能手动执行此操作。有什么想法吗?
答案 0 :(得分:2)
np.bincount
和pd.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_dummies
和pd.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
成为默认值。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']])