简单的数据操作:R vs python

Fab*_*ner 6 python r pandas data.table

我一直很高兴地使用R进行数据分析。通过数据分析,我的意思是:给定一个相对较小的表(<1 mio行,<100列),回答有关数据的“复杂”问题,例如“对于每个实例,在特定时间点变化之前发生的最后一个事件是什么?与实例”等等。

最近,我被置于人们使用python的环境中。据我所知,做这些事情的唯一包装是熊猫。尽管尝试过,但仍在(几周后)努力进行最简单的操作。让我们考虑一下这种情况:我正在查看由按SORT_NR列排序的不同事件组成的进程(由PROC_ID列标识)。出于某种奇怪的原因,我想执行以下操作:给定固定的进程ID proc_id,我想向所有SORT_NR添加一定的数字“ add”,以使SORT_NR> = start成为固定参数start。例:

PROC_ID | SORT_NR
      A |       1
      A |       2
      A |       3
      A |       4
      A |       5
      B |       1
      B |       2
Run Code Online (Sandbox Code Playgroud)

我现在使用proc_id = A,start = 3,add = 2调用此函数,这意味着预期结果将是

PROC_ID | SORT_NR
      A |       1
      A |       2
      A |       5 <<< 2 was added
      A |       6 <<< 2 was added
      A |       7 <<< 2 was added
      B |       1
      B |       2
Run Code Online (Sandbox Code Playgroud)

谷歌搜索给了我答案,这可以通过

df.loc [(df ['PROC_ID'] == proc_id)&(df ['SORT_NR']> =开始),'SORT_NR'] = df.loc [(df ['PROC_ID'] == proc_id)&( df ['SORT_NR']> =开始),'SORT_NR'] +添加

我正在明确地编写该代码,而没有对其进行格式化以使其清楚:此命令是一团糟。看着它,您没有机会轻松地了解这是什么。现在让我们看一下R的data.table包中的相应命令:

df [PROC_ID == proc_id&SORT_NR> =开始,SORT_NR:= SORT_NR +添加]

所以我们看到

  1. 在熊猫中,我们有很多重复(如果要访问它的列,您总是必须重复df,这不仅是不必要的,而且如果重命名表也是有害的)
  2. 我们还有其他一些完全不必要的特殊字符:'和方括号。那只会分散眼睛的注意力。
  3. 总的来说,我们在熊猫命令中使用154个字符,在data.table中使用68个(大约三分之一!)字符。

我不想开始一场火焰大战“ R vs python”,我只想知道:

我是否以错误的方式使用了熊猫?是否存在我无法获得的隐藏知识?

要么

熊猫不是很“有效”吗?(从某种意义上说,有很多重复和混乱使事情难以阅读和理解)

在第二种情况下:为什么有这么多人喜欢python而不是R?

编辑:还有更多令人困惑的例子。我几乎不执行会按预期做出反应的单个命令:

'EXPERIMENT_NUMBER' in process_events.columns
Out[10]: True
'EXPERIMENT_ID' in process_events.columns
Out[11]: True
process_events.drop(['EXPERIMENT_NUMBER', 'EXPERIMENT_ID'])

Traceback (most recent call last):
  ...
    raise KeyError("{} not found in axis".format(labels[mask]))
KeyError: "['EXPERIMENT_NUMBER' 'EXPERIMENT_ID'] not found in axis"
Run Code Online (Sandbox Code Playgroud)

Ada*_*ith 5

+=我知道您故意将其写得冗长,但可以使用变量和运算符将其写得更简单

df.loc[(df['PROC_ID'] == proc_id) & (df['SORT_NR'] >= start), 'SORT_NR'] = 
df.loc[(df['PROC_ID'] == proc_id) & (df['SORT_NR'] >= start), 'SORT_NR'] + add
Run Code Online (Sandbox Code Playgroud)

变成:

sorted_procs = (df['PROC_ID'] == proc_id) & (df['SORT_NR'] >= start)
df.loc[sorted_procs, 'SORT_NR'] += add
Run Code Online (Sandbox Code Playgroud)

我不了解 R,但在 Python 中,在复杂的操作中以这种方式构建事物是很常见的,这是python 禅宗的一部分。我的编写方式更有利于可读性。每行的作用一看就清楚,而且以后还可以重复使用。

您的 R 示例确实看起来更简洁,但 Python 的用途更加通用,因此这样的单行代码不一定符合设计目标。你是对的,有更多的字符来表示某些操作,但这是因为 pandas 是为 python 设计的,而 python 不是“数据优先”类型的语言。

所以回答你的问题,在这种情况下,pandas 有更多的重复,用zen写会让它更容易阅读。

  • 就像术语“数据优先”一样,这正是表达了我想说的……无论你往哪里看:人们开始使用 python 来实现这一目的:数据操作。难道只有我一个人使用非数据优先语言来解决数据优先问题吗?我一直告诉其他数据科学家:“我们不是软件开发人员,我们想快速回答问题”......但他们不听我的:-) (7认同)