我有一个文件,其中每两列包含链接数据(在此示例中只有 3 列,但可能更多),在制表符分隔的文件中:
Names SampleA Names SampleB Names SamplesC
Name1 5 Name3 7 Name1 8
Name2 9 Name2 1 Name2 2
Name4 4 Name4 8 Name3 8
等等,我想要的是有一个列,其中的列名称不包含冗余数据,在这种情况下,有 3 列包含样本;在那些不是 x 名称的值的样本中,将使用 0 进行拟合:
Names SampleA SampleB SampleC
Name1 5 0 8
Name2 9 1 2
Name3 0 7 8
Name4 4 8 0
我怎样才能用 Pandas 来处理这个矩阵?我已经尝试过使用 R 和 Perl,但我认为使用 Pandas 的 Python 会更容易!
非常感谢 !!!!
答案1
您可以按照如下方式进行操作:
使列名明确,这样您就没有同名的列(如果您愿意,也可以避免这一步,如果您通过索引访问列,但我会使它们明确):执行以下操作:
your_df.columns = ['名称A', '样本A', '名称B', '样本B', '名称', '样本C']
根据列对创建数据框
将数据框与列部分连接在一起,并将名称列折叠成一列
填充 na 值
测试数据:
import pandas as pd
your_df= pd.DataFrame({
'NamesA': ['Name1', 'Name2', 'Name4'],
'SampleA': [5, 9, 4],
'NamesB':['Name3', 'Name2', 'Name4'],
'SampleB': [5, 9, 4],
'NamesC':['Name1', 'Name2', 'Name3'],
'SampleC': [8, 2, 8]
})
这里是一些示例代码(从步骤2开始):
all_cols= list(your_df.columns)
joined_df= None
while all_cols:
name_col, sample_col, *all_cols= all_cols
# in case not all columns in your df are filled
# you need to handle na values
filled_indexer= ~your_df[name_col].isna()
# Step 2:
col_pair_df= your_df.loc[filled_indexer, [name_col, sample_col]]
# Step 3:
if joined_df is None:
joined_df= col_pair_df
joined_df.columns= ['Names', sample_col]
else:
joined_df= joined_df.merge(col_pair_df, how='outer', left_on='Names', right_on=name_col)
# now we need to populate the one names column and remove the Names* columns
names_na_indexer= joined_df['Names'].isna()
joined_df.loc[names_na_indexer, 'Names']= joined_df[name_col]
joined_df.drop(name_col, axis='columns', inplace=True)
# Step 4:
joined_df.fillna(0, inplace=True)