【问题标题】:"Can't convert float Nan to int" but no Nan?“不能将 float Nan 转换为 int”但没有 Nan?
【发布时间】:2016-03-12 05:10:41
【问题描述】:

我有一个数据框并尝试进行以下操作:

data['SD_rates']=np.array([int((data['actual value'][i]-data['means'][i])/data['std'][i]) for i in range (len(data['means']))])  

它与以下消息中断: “无法将 float Nan 转换为 int”

我理解这是一个错误,但使用 data.isnull() 测试了 df,并且没有涉及的列包含 NaN(我通过发送 data.to_csv 手动控制它)。

我什至用 fillna(-1, inplace=True) 填充了 data['std'] ,但它仍然中断了。我不明白为什么,因为没有除以 0(我还控制了该列中没有零,所以没有原始 0 和 Null/Nan 填充 -1),实际值和均值是 fillna(0 ) 用于缺失值,并且无论如何减法不能产生 nan(数据范围在 [0-10] 中)。

可能出了什么问题? (正如我所说,触发操作之前的数据是正确的......)。谢谢


这是一个代码 sn-p:
我的一个假设是,在某种程度上,groupby 可能会生成 NaN,在计算我的平均值时我无法摆脱(但我相信它被 pandas 自动忽略了......)并且没有填充 0 或-1(我故意选择-1作为标准差以避免除以0)。

def stats_setting(data):

    print('Stats settings')
    print(data.columns)
    print(data.dtypes) 
    #sys.exit()

    data['marks']=np.log1p(data['marks'].astype(float))
    data['students']=np.log1p(data['students'].astype(float))#Rossman9 think this has to be tested
    #were filled with fillna before)

#First Part: by studentType and Assortment
    types_DoM_select=['Type','Type2','Category']

#First Block:types_DoM students grouped by categories
#wonder if can do a groupby of groupb
    print("types_DoM_marks_means")
    types_DoM_marks_means = data.groupby(types_DoM_select)['marks'].mean()
    types_DoM_marks_means.name = 'types_DoM_marks_means'
    types_DoM_marks_means = types_DoM_marks_means.reset_index()
    data = pd.merge(data, types_DoM_marks_means, on = types_DoM_select, how='left')

    print("types_DoM_students_means")
    types_DoM_students_means = data.groupby(types_DoM_select)['students'].mean() #.students won't work. Why?
    types_DoM_students_means.name = 'types_DoM_students_means'
    types_DoM_students_means=types_DoM_students_means.reset_index()    
    data = pd.merge(data, types_DoM_students_means, on = types_DoM_select, how='left')

    print("types_DoM_marks_medians")
    types_DoM_marks_medians = data.groupby(types_DoM_select)['marks'].median()
    types_DoM_marks_medians.name = 'types_DoM_marks_medians'
    types_DoM_marks_medians = types_DoM_marks_medians.reset_index()
    data = pd.merge(data, types_DoM_marks_medians, on = types_DoM_select, how='left')

    print("types_DoM_students_medians")
    types_DoM_students_medians = data.groupby(types_DoM_select)['students'].median() #.students won't work. Why?
    types_DoM_students_medians.name = 'types_DoM_students_medians'
    types_DoM_students_medians=types_DoM_students_medians.reset_index()    
    data = pd.merge(data, types_DoM_students_medians, on = types_DoM_select, how='left')
    print("types_DoM_marks_std")
    types_DoM_marks_std = data.groupby(types_DoM_select)['marks'].std()
    types_DoM_marks_std.name = 'types_DoM_marks_std'
    types_DoM_marks_std = types_DoM_marks_std.reset_index()
    data = pd.merge(data, types_DoM_marks_std, on = types_DoM_select, how='left')


    print("types_DoM_students_std")
    types_DoM_students_std = data.groupby(types_DoM_select)['students'].std()
    types_DoM_students_std.name = 'types_DoM_students_std'
    types_DoM_students_std = types_DoM_students_std.reset_index()
    data = pd.merge(data, types_DoM_students_std, on = types_DoM_select, how='left')

    data['types_DoM_marks_means'].fillna(-1, inplace=True)
    data['types_DoM_students_means'].fillna(-1, inplace=True)
    data['types_DoM_marks_medians'].fillna(-1, inplace=True)
    data['types_DoM_students_medians'].fillna(-1, inplace=True)
    data['types_DoM_marks_std'].fillna(-1, inplace=True)
    data['types_DoM_students_std'].fillna(-1, inplace=True)

#Second Part: by specific student
    student_DoM_select=['Type','Type2','Category']

#First Block:student_DoM
#wonder if can do a groupby of groupb
    print("student_DoM_marks_means")
    student_DoM_marks_means = data.groupby(student_DoM_select)['marks'].mean()
    student_DoM_marks_means.name = 'student_DoM_marks_means'
    student_DoM_marks_means = student_DoM_marks_means.reset_index()
    data = pd.merge(data, student_DoM_marks_means, on = student_DoM_select, how='left')

    print("student_DoM_students_means")
    student_DoM_students_means = data.groupby(student_DoM_select)['students'].mean() #.students won't work. Why?
    student_DoM_students_means.name = 'student_DoM_students_means'
    student_DoM_students_means=student_DoM_students_means.reset_index()    
    data = pd.merge(data, student_DoM_students_means, on = student_DoM_select, how='left')

    print("student_DoM_marks_medians")
    student_DoM_marks_medians = data.groupby(student_DoM_select)['marks'].median()
    student_DoM_marks_medians.name = 'student_DoM_marks_medians'
    student_DoM_marks_medians = student_DoM_marks_medians.reset_index()
    data = pd.merge(data, student_DoM_marks_medians, on = student_DoM_select, how='left')

    print("student_DoM_students_medians")
    student_DoM_students_medians = data.groupby(student_DoM_select)['students'].median() #.students won't work. Why?
    student_DoM_students_medians.name = 'student_DoM_students_medians'
    student_DoM_students_medians=student_DoM_students_medians.reset_index()    
    data = pd.merge(data, student_DoM_students_medians, on = student_DoM_select, how='left')

    # May I use data['marks','students','marksMean','studentsMean','marksMedian','studentsMedian']=data['marks','students','marksMean','studentsMean','marksMedian','studentsMedian'].astype(int) to spare memory?

    print("student_DoM_marks_std")
    student_DoM_marks_std = data.groupby(student_DoM_select)['marks'].std()
    student_DoM_marks_std.name = 'student_DoM_marks_std'
    student_DoM_marks_std = student_DoM_marks_std.reset_index()
    data = pd.merge(data, student_DoM_marks_std, on = student_DoM_select, how='left')

    print("student_DoM_students_std")
    student_DoM_students_std = data.groupby(student_DoM_select)['students'].std()
    student_DoM_students_std.name = 'student_DoM_students_std'
    student_DoM_students_std = student_DoM_students_std.reset_index()
    data = pd.merge(data, student_DoM_students_std, on = student_DoM_select, how='left')

    data['student_DoM_marks_means'].fillna(0, inplace=True)
    data['student_DoM_students_means'].fillna(0, inplace=True)
    data['student_DoM_marks_medians'].fillna(0, inplace=True)
    data['student_DoM_students_medians'].fillna(0, inplace=True)
    data['student_DoM_marks_std'].fillna(0, inplace=True)
    data['student_DoM_students_std'].fillna(0, inplace=True)

#Third Part: Exceptional students 

    #I think int is better here as it helps defining categories but can't use it.#    
    #print(data.isnull().sum())
    #print(data['types_DoM_marks_std'][data['types_DoM_marks_std']==0].sum())
    #data.to_csv('ex')
    #print(data.columns)

#Original version:#int raises the "can't convert Nan float to int. While there were no Nan as I verified in the data just before sending it to the    
    data['Except_student_IP2_DoM_marks_means']=np.array([int((data['student_IP2_DoM_marks_means'][i]-data['types_IP2_DoM_marks_means'][i])/data['types_IP2_DoM_students_std'][i]) for i in range (len(data['year']))])  
    data['Except_student_IP2_DoM_marks_medians']=np.array([int((data['student_IP2_DoM_marks_medians'][i]-data['types_IP2_DoM_marks_means'][i])/data['types_IP2_DoM_students_std'][i]) for i in range (len(data['year']))])  
#Second version: raises no error but final data (returned) is filled with these stupid NaN
    data['Except_student_P2M_DoM_marks_means']=np.array([np.round((data['student_DoM_marks_means'][i]-data['types_DoM_marks_means'][i])/data['types_DoM_marks_std'][i],0) for i in range (len(data['year']))])  
    data['Except_student_P2M_DoM_marks_medians']=np.array([np.round((data['student_DoM_marks_medians'][i]-data['types_DoM_marks_medians'][i])/data['types_DoM_marks_std'][i],0) for i in range (len(data['year']))])  

#End
    return data

【问题讨论】:

  • 你能附上你的数据框的一部分吗?
  • 您的支票有问题。错误消息不会从无到有。
  • 尝试循环而不是列表推导,并打印每一步,看看哪里出了问题。
  • 我无法附加数据,抱歉。但我很肯定我的支票是正确的。 csv 中的文件不包含 voids 或 Nan 或任何 0。我在 excel 中控制,使用正则表达式,甚至通过在另一个没有 pb 的 python 脚本中重新加载它。谢谢你的想法,tmoreau。我会试试这个。这很奇怪,因为以相同方式计算的可比较列不会产生错误消息。所有的名字都是对的(我做了一个 ctrl+F 来检查,都在正确的地方)。
  • 您的索引看起来如何?但是,由于您正在迭代一个范围,因此您想要迭代行,最好使用.iloc[i] 而不是[i]。但更好的是,只需执行 ((data['actual value']-data['means'])/data['std']).astype(int) 迭代就不需要这样做

标签: python pandas int nan


【解决方案1】:

您的数据框中没有 Nan 很可能是正确的,但您是在计算中创建它们。请参阅以下内容:

In [15]: import pandas as pd
In [16]: df = pd.DataFrame([[1, 2], [0, 0]], columns=['actual value', 'col2'])
         df['means'] = df.mean(axis=1)
         df['std'] = df.std(axis=1)

In [17]: df
Out[17]:
   actual value  col2  means  std
0             1     2    1.5  0.5
1             0     0    0.0  0.0

所以数据框没有任何Nans,但是计算呢?

In [21]: [(df['actual value'][i]-df['means'][i])/df['std'][i] for i in range (len(df['means']))]
Out[21]: [-1.0, nan]

现在,当您调用 int 时,您会在结果列表中收到错误消息。 最后,我建议(如果可能的话)直接在底层数组中执行操作,而不是使用 for 循环,因为它会更快。

In [25]: (df['actual value']-df['means'])/df['std']
Out[25]:
0    -1
1   NaN
dtype: float64

这可能无法实现,具体取决于所需的 0 除法的返回值。

【讨论】:

  • 确实如此。我通过检查 std 是否缺少零来预料到这种情况。没有了。实际值中的所有零都表示列不会给出 NaN,在这些列中我用 0 填充了 NaN。所以我真的找不到。现在我很着急,找到了一个使用 np.round(x, 0) 的解决方法,这似乎没有问题,但是当我有一点时间时,我会回来做一个 for 循环和仔细检查结果。
  • 可能是您的标准差列中没有任何零,在这种情况下,返回 Nans 的计算中还有其他内容。如果没有产生错误的最小工作示例,那么弄清楚这一点将非常困难。很高兴你让它工作,我鼓励你发布一个产生错误的代码的小例子,因为它可能会帮助其他人。
  • 嗯,实际上,它“有效”,因为它不会引发错误。但最终的表格充满了这些愚蠢的缺失数据。这让我抓狂,我认为 np.round 在计算时会产生 NaN ,并且不会引发错误。还是那样坏了。我将编辑我的 OP 以包含两个代码的 sn-p。谢谢
猜你喜欢
  • 2017-06-18
  • 1970-01-01
  • 2022-07-07
  • 2019-12-26
  • 2023-01-20
  • 2023-04-09
  • 2020-01-21
  • 1970-01-01
  • 2015-05-12
相关资源
最近更新 更多