复制csv的每一列,并根据python中的条件更改每一列单元格的值

复制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

我是所有东西的新用户,尤其是python和pandas。我有一个.csv文件,有1000多列和大约250行。行的值为0和1或空单元格。csv文件的示例如下所示:

  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]})