bounty将在6天后过期。回答此问题可获得+50的声望奖励。Thavas Antonio希望吸引更多人关注此问题。
我正在尝试根据if条件在for循环中改变 Dataframe 。
import pandas as pd
# read the read.csv file
def write_csv(email, info):
df1 = pd.read_csv('/Users/thavas/Downloads/write.csv')
#iterate over df1 and look for email
for index, row in df1.iterrows():
print(index)
if row['Email 1'] == email:
#change the value of column 8 to "hello"
df1.loc[index,'Email 2'] = "hello"
df1.to_csv('/Users/thavas/Downloads/out.csv')
def read_csv():
#iterate over rows in dataframe
df = pd.read_csv('/Users/thavas/Downloads/read.csv')
for index,rows in df.iterrows():
email = rows['Email']
#if email available
if email != 'nan':
#get column 8,9,10,11 of rows
info = rows[8:17]
write_csv(email, info)
else:
print("Users", rows['Contact'], "has no email")
read_csv()
然而,我遇到了一个错误,在使用if语句时,没有数据被添加到csv文件中。
通过调试,我意识到通过在if语句中加入print语句,我可以得到很多输出,所以加入if语句不是问题。
此外,在取出所有的if语句后,我看到输出到我的csv文件中。可能出了什么问题?
UPDATE我注意到只有最后一个循环的数据被读取并更新到我的输出文件。
这是什么意思呢?
1条答案
按热度按时间ajsxfq5m1#
为了便于解释,我简化了问题,在
read.csv
中只使用了三列(eid
、name
和email
),而write.csv
中有(email1
和email2
)。我们的目标是创建
out.csv
,它是write.csv
的副本,其中email 2字段填充了read.csv
中存在的所有电子邮件。下面的代码符合您的大部分逻辑,我将用它来强调一些问题。
和输出
参考1:
这真的取决于你的csv文件和你希望在那里找到什么。如果空邮件在你的文件中实际上是用“nan”表示的,那么这似乎没问题。但是,在我的例子中,文件实际上没有任何关于丢失邮件的内容(
''
)。所以Pandas把它们写成NaN
。但是,你不能直接把它和'nan'
进行比较。可能的解决方案
if str(email) == 'nan'
作为字符串(nan)是'nan'
if isinstance(email, float) and np.isnan(email)
这里的np.isnan
是numpy的一个函数,但它只对浮点数有效。给它一个字符串会导致错误。1.在开始时将整列转换为字符串,然后遍历行。
pd.read_csv('./read.csv').astype({'email':'str'})
。然后,您可以像以前一样比较email == 'nan'
。1.仅迭代非nan值。例如,
for index, rows in df[~df.email.isna()].iterrows()
,其中df.email.isna()
检查某个值是否为NaN,并且~
将其取反。因此,您将获得电子邮件不是NaN的所有行。这样,就可以保证
write_csv
会被正确调用。参考文献2:
每次迭代都写
out.csv
的代价很高。如果write.csv
有1000行,那么你将写out.csv
1000次。相反,你只需要在for循环之外写一次out.csv
。参考文献3和4:
当你从
read.csv
中找到一个非空的email时,write_csv
被调用来处理一个特定的email。例如,让我们取第一行,tom@stackoverflow.com
。所以现在write_csv
读取write.csv
,修改email为tom...
的所有示例,然后将其写入out.csv
。除了当它移动到下一个非空电子邮件
bob...
时,您再次从write.csv
读取,它覆盖了out.csv
。write.csv
没有您对tom
所做的更改。这解释了为什么您只会看到最后一封电子邮件。可能的解决方案:
1.一个快速的解决方法是首先将
write.csv
复制到out.csv
(在调用read_csv
之前),然后修改write_csv
,使其始终读取out.csv
并写入out.csv
。总结一下:
上面的代码将为您提供一个有效的解决方案,但仍然效率低下,因为您要为每一封存在的电子邮件编写
out.csv
。相反,考虑通过合并/连接
read.csv
和write.csv
的 Dataframe 来创建out.csv
。这里有一些merge和join文档的链接。也许还可以看看panda连接和合并的堆栈溢出问题的一些示例。