大数据情况下如何排查代码

Posted

技术标签:

【中文标题】大数据情况下如何排查代码【英文标题】:How to troubleshoot code in the case of big data 【发布时间】:2014-07-06 07:36:15 【问题描述】:

我正在尝试实现一个表的this python solution to count the number of lines with identical content in the first few columns。这是我的代码:

#count occurrences of reads
import pandas as pd
#pd.options.display.large_repr = 'info'
#pd.set_option('display.max_rows', 100000000)
#pd.set_option('display.width',50000)

import sys
file1 = sys.argv[1]
file2 = file1[:4] + '_multi_nobidir_count.soap'

df = pd.read_csv(file1,sep='\t',header=None)
df.columns = ['v0','v1','v2','v3','v4','v5','v6','v7','v8','v9','v10','v11']
df['v3']=df.groupby(['v0','v1','v2']).transform(sum).v3
df.to_csv(file2,sep='\t',index=False,header=False)

它适用于测试数据(200 行),但当我将其应用于真实数据(2000 万行)时出现以下错误:

Traceback (most recent call last):
  File "count_same_reads.py", line 14, in <module>
    df['v3']=df.groupby(['v0','v1','v2']).transform(sum).v3
  File "/usr/local/lib/python2.7/dist-packages/pandas-0.14.0-py2.7-linux-x86_64.egg/pandas/core/groupby.py", line 2732, in transform
    return self._transform_item_by_item(obj, fast_path)
  File "/usr/local/lib/python2.7/dist-packages/pandas-0.14.0-py2.7-linux-x86_64.egg/pandas/core/groupby.py", line 2799, in _transform_item_by_item
    raise TypeError('Transform function invalid for data types')
TypeError: Transform function invalid for data types

如何进行故障排除,找出我收到此错误的原因?

[编辑] 取消注释 pd.options.pd.set_option 行并没有改变结果。

[EDIT2] 考虑到下面的一些回复,我在我的数据上运行了以下代码以输出第 4 列中没有数字的任何数据行:

#test data type
import sys
file1 = sys.argv[1]

def is_number(s):
    try:
        float(s)
        return True
    except ValueError:
        return False

with open(file1, 'r') as data:
    for row in data:
        a = row.strip().split()[3]
        if is_number(a) == False:
            print row.strip()

这适用于测试数据,其中我将行的第四列值之一从1 更改为e,它只输出包含字母而不是数字的行。我在原始大数据上运行它,但没有返回任何行。

【问题讨论】:

也许只转换v3 列有效:df.v3 = df.groupby(['v0','v1','v2']).v3.transform(sum) 【参考方案1】:

您收到的异常是TypeError,它暗示文件存在问题。但是对于大文件,处理比较的代码总是可能存在例如内存问题。所以,你有两种可能:

文件损坏 代码(您的或pandas 的)已损坏

为了调试它,您可以尝试将您的文件分段输入到您的代码中。在某些时候,您已经隔离了问题。它可能是两者之一:

无论您使用哪 n 行,它都会引发异常(但不是 n-1 行);内存管理或其他东西坏了 可以将问题隔离到数据文件的一行或多行;数据文件损坏

我第二个merlin2011 的猜测:你的文件中有一些意想不到的东西。 pandas 不太可能只记录 200 000 000 条记录。

【讨论】:

谢谢。我尝试检查原始数据以查看我正在计算的列是否包含除数字之外的任何其他内容,但显然它没有...我编辑了 OP 以显示我是如何做到的。但是您认为这足以排除“文件已损坏”选项吗? 不幸的是,事实并非如此。您使用的其他列之一(第 1、2、3 列)中可能有错误数据。另一方面,如果你不缺硬盘空间,告诉 linux 到tail +1234567 mydata.csv | head -n 10000 生成测试文件不会花费那么多时间。 我解决了这个问题,但忘了检查答案。我的数据文件确实坏了:)【参考方案2】:

打开文件/usr/local/lib/python2.7/dist-packages/pandas-0.14.0-py2.7-linux-x86_64.egg/pandas/core/groupby.py,转到第2799行。

就在以下语句之前,在相同的缩进级别中,添加一行以打印违规数据的值。

raise TypeError('Transform function invalid for data types')

现在,在TypeError 被抛出之前,您将知道是什么数据导致了错误。

鉴于您要求和,我推测您的列中有一个非数字值,但我没有您的数据,所以这纯粹是推测。


我快速查看了发生错误的代码区域,在这种情况下,您应该在引发TypeError 之前检查对象obj

for i, col in enumerate(obj):
    try:
        output[col] = self[col].transform(wrapper)
        inds.append(i)
    except Exception:
        pass

if len(output) == 0:  # pragma: no cover
    raise TypeError('Transform function invalid for data types')

【讨论】:

谢谢。你的意思是我应该添加print obj【参考方案3】:

以下是解决此类问题的方法:

创建一个函数来包装操作(这会慢一些,因为它没有被cythonized),但应该能捕捉到你的错误。

def f(x):
    try:
        return x.sum()
    except:
        import pdb; pdb.set_trace()


df['v3']=df.groupby(['v0','v1','v2']).transform(f).v3

【讨论】:

以上是关于大数据情况下如何排查代码的主要内容,如果未能解决你的问题,请参考以下文章

大数据问题排查系列 - HDFS FileSystem API 的正确打开方式,你 GET 了吗?

Kubernetes 应用问题的通用排查思路 - 大数据从业者之 Kubernetes 必知必会

数据库查询慢-排查问题总结

大数据量情况下高效比较两个list

大数据问题排查系列-大数据集群开启 kerberos 认证后 HIVE 作业执行失败

如何在没有日志的情况下删除SQL中表的大数据?