我有一个这样的文本文件:
444537110 3 11112111022002200022022111121222002...
输入文件中的最后一个字段的长度为50k个字符,并且只有0、1或2个字符。我想要最后一个字段的一个热编码版本。因此,我的预期结果是这样的数据帧:
id chip g1_0 g1_1 g1_2 g2_0 g2_1 g2_2 g3_0 g3_1 g3_2 g4_0 ...
444537110 3 0 1 0 0 1 0 0 1 0 0
我通过读取输入文件创建了一个初始数据帧:
df = pd.read_csv('test.txt', index_col=0, sep='\s+', header=None, names = ['chip', 'genos'])
这将创建一个包含3列的数据帧:
id chip genos
444537110 3 1111211102200220000022022111121222000200022002...
我想我也许可以使用下面的东西创建初始的单独列,然后使用熊猫get_dummies函数进行一次热编码,但是我无法创建单独的列。我已经试过了
[c for c in df['genos'].str]
但这并不是把角色分开
我在这里看到了一个类似的问题和答案:如何用Python进行热编码?
但这只处理一个热编码,不处理拆分一个非常大的列的额外复杂性
如果只拆分50k个字符,可以使用原始Python(为了可读性):
>>> a,b,c = zip(*[{0:(1,0,0),1:(0,1,0),2:(0,0,1)}[int(c)] for c in df['genos'][0]])
>>> a,b,c
((0, 0, 0, 0, 0, 0, ...), (1, 1, 1, 1, 0, 1, ...), (0, 0, 0, 0, 1, 0, ...))
考虑到@Dan对你的问题的评论,关于你将以50k*3列结束,你可以通过这样做得到你想要的输出:
string ="444537110 3 11112111022002200022022111121222002"
df = pd.DataFrame([string.split(" ")],columns=['id','chip','genos'])
max_number_of_genes = int(df.genos.apply(lambda x : len([y for y in x])).max())
#Create columns
for gene in range(1,max_number_of_genes+1):
for y in range(4):
df['g{}_{}'.format(gene, y)] = 0
#Iterating over genos values
for row_number, row in df.iterrows():
genos = [int(x) for x in df.iloc[row_number, 2]]
for gene_number, gene in enumerate(genos):
df.loc[row_number, 'g{}_{}'.format(gene_number+1, gene)] = 1
print(df)
输出
+----+------------+-------+--------------------------------------+-------+-------+-------+-------+-------+-------+-------+------+--------+--------+--------+--------+--------+--------+--------+--------+--------+-------+
| | id | chip | genos | g1_0 | g1_1 | g1_2 | g1_3 | g2_0 | g2_1 | g2_2 | ... | g33_2 | g33_3 | g34_0 | g34_1 | g34_2 | g34_3 | g35_0 | g35_1 | g35_2 | g35_3 |
+----+------------+-------+--------------------------------------+-------+-------+-------+-------+-------+-------+-------+------+--------+--------+--------+--------+--------+--------+--------+--------+--------+-------+
| 0 | 444537110 | 3 | 11112111022002200022022111121222002 | 0 | 1 | 0 | 0 | 0 | 1 | 0 | ... | 0 | 0 | 1 | 0 | 0 | 0 | 0 | 0 | 1 | 0 |
+----+------------+-------+--------------------------------------+-------+-------+-------+-------+-------+-------+-------+------+--------+--------+--------+--------+--------+--------+--------+--------+--------+-------+
首先创建DataFrame
,将字符串转换为列表并调用get_dummies
:
df1 = pd.DataFrame([list(x) for x in df['genos']], index=df.index).add_prefix('g')
df2 = pd.get_dummies(df1)
如果需要将新列添加到原始列(如果可能缺少某些组合),请使用DataFrame。通过带
的拆分列以及由
多索引创建的所有组合重新编制索引。来自产品
:
df1 = pd.DataFrame([list(x) for x in df.pop('genos')], index=df.index).add_prefix('g')
df2 = pd.get_dummies(df1)
splitted = df2.columns.str.split('_')
df2.columns = [splitted.str[0].astype(int) + 1, splitted.str[1].astype(int)]
#
mux = pd.MultiIndex.from_product([df2.columns.get_level_values(0), [0,1,2]])
df2 = df2.reindex(mux, axis=1, fill_value=0)
df2.columns = [f'g{a}_{b}' for a, b in df2.columns]
print (df2)
g1_0 g1_1 g1_2 g2_0 g2_1 g2_2 g3_0 g3_1 g3_2 g4_0 ... g32_2 \
0 0 1 0 0 1 0 0 1 0 0 ... 1
g33_0 g33_1 g33_2 g34_0 g34_1 g34_2 g35_0 g35_1 g35_2
0 1 0 0 1 0 0 0 0 1
[1 rows x 105 columns]
我有一个pyspark数据帧,如下所示: 以及以下国家的名单: 我想做以下工作: 从列 为。对于,创建一个名为的列。基本上,为列出一个名为的额外列 如果包含列表中的任何国家,则新列应具有作为值,否则。这同样适用于列表中的其他国家 如果包含
我试图在Iris数据集中的目标列(“物种”)上使用一个热编码器。 但我得到了以下错误: ValueError:预期的2D数组,得到1D数组代替: 使用数组或数组重塑数据的形状。如果数据具有单个要素或阵列,则重塑(-1,1)。如果(1,-1)包含单个样本,则重塑其形状。 我在谷歌上搜索了这个问题,发现大多数scikit学习估计器都需要2D数组,而不是一维数组。 同时,我还发现,我们可以尝试传递带有索
问题内容: 我有一个具有这种结构的表。 我无法弄清楚我将使用哪种SQL查询来获得这样的结果集: 我正在尝试将三列分为三个单独的行。这可能吗? 问题答案: SELECT Y.UserID, Y.UserName, QuestionName = ‘AnswerToQuestion’ + X.Which, Response = CASE X.Which WHEN ‘1’ THEN AnswerToQue
我有: 我想要: 似乎在scala中我可以写:< code>df.select($"value。_1 ",$ "值。_2 ",$ "值。_3"),但这在python中是不可能的。 那么有没有好的办法呢?
我有一个列,其中包含该列的名称和值,格式如下: 我不想使用上面的设置,而是希望按以下格式排列列: 问题是这些值在整个列中并不一致,有时我会有这些值的组合,有时没有,有时只有一个,但顺序如何并不重要,所有这些列都必须创建。怎样才能用一种通用的方式调用它们,而不用像这样指定值:
如何将这列列表拆分为两列? 期望的结果: