Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/363.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 如何将数据框附加到csv,并在必要时创建新列?_Python_Pandas_Dataframe - Fatal编程技术网

Python 如何将数据框附加到csv,并在必要时创建新列?

Python 如何将数据框附加到csv,并在必要时创建新列?,python,pandas,dataframe,Python,Pandas,Dataframe,因此,我有一个名为df的输出,它来自一个pandas数据框,该数据框是在这样的许多电影循环中创建的,因此每个df都是一部电影的数据: df = pandas.get_dummies(data=df, columns=['genre1', 'genre2', 'genre3', 'genre4']) df = df.rename(columns=lambda x: x.replace('genre1_', '')) df = df.rename(columns=lambda x: x.replac

因此,我有一个名为
df
的输出,它来自一个pandas数据框,该数据框是在这样的许多电影循环中创建的,因此每个
df
都是一部电影的数据:

df = pandas.get_dummies(data=df, columns=['genre1', 'genre2', 'genre3', 'genre4'])
df = df.rename(columns=lambda x: x.replace('genre1_', ''))
df = df.rename(columns=lambda x: x.replace('genre2_', ''))
df = df.rename(columns=lambda x: x.replace('genre3_', ''))
df = df.rename(columns=lambda x: x.replace('genre4_', ''))
df = pd.concat([df[col].sum(axis=1).rename(col) if len(df[col].shape)==2 else
                df[col] for col in df.columns.unique()],axis=1)
print(df)
with open('test.csv', 'a') as f:
    df.to_csv(f, mode='a', header=f.tell()==0)
但问题是每个循环之前都有不同的类型

因此,对于第一个循环,输出如下所示:

title运行时喜剧动作剧传记。。。。。。
电影1 90分钟1
然后将其分配给csv

但在循环的下一次迭代中,下一部电影如下所示:

标题运行时喜剧动作历史。。。。。。
电影2 90分钟1
我现在想创建一个名为
history
的新列,并在该行中为
film2
创建一个列,但为
film1
创建一个
0
列,并将
0
分配给
film2
上的
传记
戏剧

目前,它只是创建第一部电影作为默认电影,然后认为其他每部电影都有相同的类型

因此,第一次迭代生成的df如下所示:

第二次迭代如下所示:

添加到CSV文件是不可能的,因为您冻结了标题,并且还没有所有可能的标题

一种更简单的方法是创建完整的数据帧,只有这样才能与之前的方法相同,请参见下一个示例代码:

# initialize full dataframe    
df_full = pd.DataFrame()
#... loop reading df of one film data
# once created the raw df, you would do:
df_full = pd.concat([df_full,df])
# when finished run you're code on df_full like:
df_full = pandas.get_dummies(data=df_full, columns=['genre1', 'genre2', 'genre3', 'genre4'])
# continue with the rest of your code, eventually writing the csv file
根据OP的评论,我已经编写了处理这种情况的代码, 当无法在内存中执行此操作时:

# initialize the full set of genres list and genre fix columns
full_genre_cols = set()
genre_cols = ['genre1', 'genre2', 'genre3', 'genre4']
# taking created raw dataframe and keeping new genres
df = pd.get_dummies(df, columns=genre_cols, prefix_sep='', prefix='')
actual_genre_cols = df.drop(non_genre_cols, axis=1).columns
full_genre_cols.update(actual_genre_cols)
# ... finish reading all dataframes, and start over 
# this time create full columns dataframes, and append them to CSV file
# preparing raw df and transform
non_genre_cols = df.drop(genre_cols, axis=1).columns
df = pd.get_dummies(df, columns=genre_cols, prefix_sep='', prefix='')
actual_genre_cols = df.drop(non_genre_cols, axis=1).columns
# preparing full columns dataframe
full_cols = list(non_genre_cols)
full_cols.extend(full_genre_cols)
df_fullcols = pd.DataFrame(columns=full_cols)
# updating with current values the correct genre columns
# and resetting to 0 all NaN of genres that not exist in this current cycle
df_fullcols[actual_genre_cols] = df[actual_genre_cols]
df_fullcols.fillna(0, inplace=True)
# and now only left to append to file
with open('test.csv', 'a') as f:
    df_fullcols.to_csv(f, mode='a', header=f.tell()==0)

我被你的更名代码搞糊涂了,你能告诉我吗?如果我们能看到列名的前后,那也很好。因此,代码在csv格式的电影列表上循环。然后,它首先生成一个包含所有信息的熊猫数据帧;标题、长度、类型等。然后,对于每部电影,将类型1、类型2、类型3和类型4转换为喜剧、动作等列,加上1和0。然后在每一行(电影)中附加csv“测试”,但由于get_dummies部分的原因,每一次迭代都有不同的标题。好的,告诉我是否正确理解了您的评论。你有一堆数据帧,每一帧都包含一部电影的信息。您试图将所有这些数据帧合并为一个,每一个电影都在一行上,并有一组列指示电影是否属于某一类型。我曾尝试这样做,但在创建将每个列表附加到数据帧,然后将entird df输出到csv时,出现了内存错误。appraoch应该是相同的,也就是说,您首先需要读取所有数据,但只需要创建一个包含所有读取列的集合(每个类型仅显示一次)。只有在这一次重新读取数据时,才能写入一个设置了所有列的标题,并且每次创建一个胶片df时,它应该包含所有设置的列,因此它将在适当的位置以正确的值附加到CSV(在这个读取周期中不存在的标题为零)。然而,除非您有一个非常大的列表(数百万行),或者内存非常低的系统(小于4GB),否则您应该检查您的代码,因为它不应该出现内存错误。