复制csv的每一列,并根据python中的条件更改每一列单元格的值
我是所有东西的新用户,尤其是python和pandas。我有一个.csv文件,有1000多列和大约250行。行的值为0和1或空单元格。csv文件的示例如下所示:复制csv的每一列,并根据python中的条件更改每一列单元格的值,python,excel,pandas,numpy,csv,Python,Excel,Pandas,Numpy,Csv,我是所有东西的新用户,尤其是python和pandas。我有一个.csv文件,有1000多列和大约250行。行的值为0和1或空单元格。csv文件的示例如下所示: ID col1 col2 col3 col4 . . ............... col1000 1 1 0 1 1 2 0
ID col1 col2 col3 col4 . . ............... col1000
1 1 0 1 1
2 0 1 1
3 1 0 0
.
.
.
.
250 0 1 0 0
我想做两件事:
首先,我要复制与原始列具有相同单元格值和列名的所有1000列(ID列除外),然后按以下顺序将每个复制的列放置在原始列旁边:
col1 col1 col2 col2 col3 col3 col4 col4 ...... col1000 col1000
其次,我想根据以下条件替换单元格中的值:
如果原始单元格中有1,则复制列中的值应保持为1;如果原始列单元格中有0,则复制列的值应更改为-1。如果原始单元格为空,则原始单元格和复制单元格的值应填充为0
输出的csv文件将是:
ID col1 col1 col2 col2 col3 col3 col4 col4 . ........... col1000 col1000
1 1 1 0 -1 0 0 1 1 1 1
2 0 -1 0 0 1 1 1 1 0 0
3 0 0 1 1 0 0 0 -1 0 -1
.
.
.
.
250 0 -1 1 1 0 0 0 -1 0 -1
我无法解决这个问题,如果有人能帮助我,我真的很感激;谢谢…您可以试试看它是否有效
import pandas as pd
import numpy as np
起始数据
df = pd.DataFrame({'col1':[1,0,np.NaN,np.NaN,1],'col2':[1,0,np.NaN,np.NaN,1],'col3':[1,0,np.NaN,np.NaN,1]})
首先复制原始df
df_copy = df.copy()
然后根据上述条件替换副本中的值
columns = df_copy.columns
df_copy[columns] = np.where(df_copy[columns]==0,-1,df_copy[columns])
然后填充空白值为0。
df_copy = df_copy.fillna(0)
添加用于排序的列计数
df.loc['total'] = np.arange(len(df.columns))
df_copy.loc['total'] = np.arange(len(df_copy.columns))
然后将两个df连接在一起
new_df = pd.concat([df,df_copy],axis=1)
使用列计数行对列进行排序,然后从新df中删除该行
new_df = new_df.sort_values(by='total',axis=1)
new_df = new_df.loc[~new_df.index.isin(['total'])]
您可以使用此方法(与其他答案类似,使用内置函数替换):
输出和样本输入(对于不同的输入样本,但列比较明显):
输入:
ID col1 col2 col3 col4 col1000
0 1 1 0 1 1.0 NaN
1 2 0 1 1 NaN NaN
2 3 1 0 0 NaN NaN
250 250 0 1 0 0.0 NaN
输出:
ID col1 col2 col3 col4 ... col1000 col1 col2 col3 col4 ... col1000
0 1 1 0 1 1.0 0.0 1 -1 1 1.0 0.0
1 2 0 1 1 0.0 0.0 -1 1 1 0.0 0.0
2 3 1 0 0 0.0 0.0 1 -1 -1 0.0 0.0
...
250 250 0 1 0 0.0 0.0 -1 1 -1 -1.0 0.0
您可以执行以下步骤,诀窍是使用列索引获得正确的列序列:
# create copied data and concat into original
df2 = pd.concat([df, df.replace(0,-1).fillna(0).drop('ID', axis=1)], 1)
# since column names are same, we need to use index
cols = [x for x in df2.columns if x != 'ID']
cols = dict(enumerate(cols))
# get correct index for column names
cols_index = [x[0] for x in sorted(cols.items(), key=lambda x: x[1])]
# fix column names
idcol = df2[['ID']]
df2 = df2.drop('ID', 1).iloc[:,cols_index]
# add the ID column
df2 = pd.concat([idcol, df2], 1).fillna(0)
print(df2)
ID col1 col1 col2 col2 col3 col3
0 1 1.0 1.0 1.0 1.0 1.0 1.0
1 2 0.0 0.0 0.0 0.0 0.0 0.0
2 3 NaN -1.0 NaN -1.0 NaN -1.0
3 4 NaN -1.0 NaN -1.0 NaN -1.0
4 5 1.0 1.0 1.0 1.0 1.0 1.0
样本数据
不,它给出了两个错误:A:“AttributeError:'numpy.ndarray'对象没有属性'fillna'。如果我将fillna放在np.where行之前,那么第二个错误是:B:TypeError:无法连接类型为“”的对象;只有Series和DataFrame OBJ是有效的。我删除了错误,现在可以正常工作了,但是输出文件不是我所需要的。你是否将pandas作为pd导入,将numpy作为np导入?我查看了代码,意识到我跳过了一步。。。以上修改感谢您的帮助,我运行了代码,但很抱歉,它没有提供所需的输出,尽管它根据条件替换了值,但仅在复制的数据帧中,该数据帧是文件的后半部分,并且有空单元格,并且我提到的顺序不存在,因为顺序很重要,我的意思是复制的单元格应该在原始单元格后面,比如col1 col1 col2 col2,而concatenate确实给出了这个顺序。谢谢你的回答,但是有没有办法保持我所需要的顺序?我必须进一步处理数据,为此我需要与我在相关输出文件中提到的相同的顺序。每个复制的列必须位于原始列(如col1 col1 col2 col2 col3 col3和son on)之后,否则不起作用。有10000多列和250多行,因此无法对它们进行比较manually@codeDB您是否关心它们是否具有相同的列名,或者它们的名称中是否具有例如后缀
col1_old
和col1_new
没有问题,但是列的顺序和位置不应该改变,这要感谢它的工作,特别是所需列的顺序,但是在原始列中(不是复制的),nan值不会替换为零,但我可以这样做,而且-1替换也不会替换nan值,但仅当原始列单元格中的值为0时,复制的单元格中应该有-1,我也可以更正。非常感谢…@codeDB谢谢你的反馈,我已经更新了答案。如果有用,请将其标记为已接受。嗨,对不起,我刚刚意识到我的数据中有一个错误。价值置换的条件是错误的。如果原始单元格(col1)的值为1,则同一复制的单元格(col1)的值应为-1,并且原始单元格的值保持为1。类似地,如果原始单元格的值为0,则原始单元格的0应更改为-1,并且相同复制单元格的值应为1。对于空单元格,规则是相同的,原始单元格和复制单元格都应使用0填充。我用df.replace({a:b,b:c})函数尝试了一下,但没有成功。你能帮我解决这个问题吗?
# create copied data and concat into original
df2 = pd.concat([df, df.replace(0,-1).fillna(0).drop('ID', axis=1)], 1)
# since column names are same, we need to use index
cols = [x for x in df2.columns if x != 'ID']
cols = dict(enumerate(cols))
# get correct index for column names
cols_index = [x[0] for x in sorted(cols.items(), key=lambda x: x[1])]
# fix column names
idcol = df2[['ID']]
df2 = df2.drop('ID', 1).iloc[:,cols_index]
# add the ID column
df2 = pd.concat([idcol, df2], 1).fillna(0)
print(df2)
ID col1 col1 col2 col2 col3 col3
0 1 1.0 1.0 1.0 1.0 1.0 1.0
1 2 0.0 0.0 0.0 0.0 0.0 0.0
2 3 NaN -1.0 NaN -1.0 NaN -1.0
3 4 NaN -1.0 NaN -1.0 NaN -1.0
4 5 1.0 1.0 1.0 1.0 1.0 1.0
df = pd.DataFrame({'ID': list(range(1,6)),
'col1':[1,0,np.NaN,np.NaN,1],
'col2':[1,0,np.NaN,np.NaN,1],
'col3':[1,0,np.NaN,np.NaN,1]})