我对以下问题感到困惑。我有一组csv文件,我会迭代解析。在收集列表中的数据帧之前,我将一些函数(简单为tmp_df*2
)应用于每个tmp_df
。乍一看,这一切都完美无缺,直到我意识到我与运行结果不一致。
例如,当我申请df.std()
时,我可能会收到第一次运行:
In[2]: df1.std()
Out[2]:
some_int 15281.99
some_float 5.302293
并且在第二次运行之后:
In[3]: df2.std()
Out[3]:
some_int 15281.99
some_float 6.691013
扼杀,当我不操纵解析数据时(我只是注释掉tmp_df = tmp_df*2
),我不会发现像这样的不一致。我还注意到,对于我有数据类型int
的列,结果在运行之间是一致的,这不适用于floats
。我怀疑它与精度点有关。我也无法确定它们如何变化的模式,可能是我连续两次或三次运行的结果相同。也许有人知道我在这里遗失了什么。我正在研究复制示例,我将尽快编辑,因为我无法共享基础数据。也许有人可以在此期间对此有所了解。我使用的是win8.1,pandas 17.1,python 3.4.3。
代码示例:
import pandas as pd
import numpy as np
data_list = list()
csv_files = ['a.csv', 'b.csv', 'c.csv']
for csv_file in csv_files:
# load csv_file
tmp_df = pd.read_csv(csv_file, index_col='ID', dtype=np.float64)
# replace infs by na
tmp_df.replace([np.inf, -np.inf], np.nan, inplace=True)
# manipulate tmp_df
tmp_df = tmp_df*2
data_list.append(tmp_df)
df = pd.concat(data_list, ignore_index=True)
df.reset_index(inplace=True)
更新
在UX系统上运行相同的代码和数据非常正常。
编辑:
我设法重新创建了问题,它应该在win和ux上运行。我已经在win8.1上测试了with_function=True
(通常在1-5次运行后)遇到同样的问题,在ux上运行没有问题。 with_function=False
在win和ux中没有差异。我也可以拒绝与int
或float
问题相关的假设,因为模拟的int
也不同......
以下是代码:
import pandas as pd
import numpy as np
from pathlib import Path
from tempfile import gettempdir
def simulate_csv_data(tmp_dir,num_files=5):
""" simulate a csv files
:param tmp_dir: Path, csv files are saved to
:param num_files: int, how many csv files to simulate
:return:
"""
rows = 20000
columns = 5
np.random.seed(1282)
for file_num in range(num_files):
file_path = tmp_dir.joinpath(''.join(['df_', str(file_num), '.csv']))
simulated_df = pd.DataFrame(np.random.standard_normal((rows, columns)))
simulated_df['some_int'] = np.random.randint(0,100)
simulated_df.to_csv(str(file_path))
def get_csv_data(tmp_dir,num_files=5, with_function=True):
""" Collect various csv files and return a concatenated dfs
:param tmp_dir: Path, csv files are saved to
:param num_files: int, how many csv files to simulate
:param with_function: Bool, apply function to tmp_dataframe
:return:
"""
data_list = list()
for file_num in range(num_files):
# current file path
file_path = tmp_dir.joinpath(''.join(['df_', str(file_num), '.csv']))
# load csv_file
tmp_df = pd.read_csv(str(file_path), dtype=np.float64)
# replace infs by na
tmp_df.replace([np.inf, -np.inf], np.nan, inplace=True)
# apply function to tmp_dataframe
if with_function:
tmp_df = tmp_df*2
data_list.append(tmp_df)
df = pd.concat(data_list, ignore_index=True)
df.reset_index(inplace=True)
return df
def main():
# INPUT ----------------------------------------------
num_files = 5
with_function = True
max_comparisons = 50
# ----------------------------------------------------
tmp_dir = gettempdir()
# use temporary "non_existing" dir for new file
tmp_csv_folder = Path(tmp_dir).joinpath('csv_files_sdfs2eqqf')
# if exists already don't simulate data/files again
if tmp_csv_folder.exists() is False:
tmp_csv_folder.mkdir()
print('Simulating temp files...')
simulate_csv_data(tmp_csv_folder, num_files)
print('Getting benchmark data frame...')
df1 = get_csv_data(tmp_csv_folder, num_files, with_function)
df_is_same = True
count_runs = 0
# Run until different df is found or max runs exceeded
print('Comparing data frames...')
while df_is_same:
# get another data frame
df2 = get_csv_data(tmp_csv_folder, num_files, with_function)
count_runs += 1
# compare data frames
if df1.equals(df2) is False:
df_is_same = False
print('Found unequal df after {} runs'.format(count_runs))
# print out a standard deviations (arbitrary example)
print('Std Run1: \n {}'.format(df1.std()))
print('Std Run2: \n {}'.format(df2.std()))
if count_runs > max_comparisons:
df_is_same = False
print('No unequal df found after {} runs'.format(count_runs))
print('Delete the following folder if no longer needed: "{}"'.format(
str(tmp_csv_folder)))
if __name__ == '__main__':
main()
答案 0 :(得分:0)
您的变体是由其他内容引起的,例如执行之间的输入数据更改或源代码更改。
浮点精度在执行之间不会产生不同的结果。
顺便说一句,清理你的例子,你会发现错误。此时你会说一些关于和int但是显示一个十进制值而不是!!
答案 1 :(得分:0)
将numexpr更新为2.4.6(或更高版本),因为numexpr 2.4.4在Windows上有一些错误。运行更新后,它适用于我。