10You can use RDataFrame in Python thanks to the dynamic Python/C++ translation of [PyROOT](https://root.cern/manual/python). In general, the interface
11is the same as for C++, a simple example follows.
12
13~~~{.py}
14df = ROOT.RDataFrame("myTree", "myFile.root")
15sum = df.Filter("x > 10").Sum("y")
16print(sum.GetValue())
17~~~
18
19### User code in the RDataFrame workflow
20
21#### C++ code
22
23In the simple example that was shown above, a C++ expression is passed to the Filter() operation as a string
24(`"x > 0"`), even if we call the method from Python. Indeed, under the hood, the analysis computations run in
25C++, while Python is just the interface language.
26
27To perform more complex operations that don't fit into a simple expression string, you can just-in-time compile
28C++ functions - via the C++ interpreter cling - and use those functions in an expression. See the following
29snippet for an example:
30
31~~~{.py}
32# JIT a C++ function from Python
33ROOT.gInterpreter.Declare("""
34bool myFilter(float x) {
35 return x > 10;
36}
37""")
38
39df = ROOT.RDataFrame("myTree", "myFile.root")
40# Use the function in an RDF operation
41sum = df.Filter("myFilter(x)").Sum("y")
42print(sum.GetValue())
43~~~
44
45To increase the performance even further, you can also pre-compile a C++ library with full code optimizations
46and load the function into the RDataFrame computation as follows.
47
48~~~{.py}
49ROOT.gSystem.Load("path/to/myLibrary.so") # Library with the myFilter function
50ROOT.gInterpreter.Declare('#include "myLibrary.h"') # Header with the declaration of the myFilter function
51df = ROOT.RDataFrame("myTree", "myFile.root")
52sum = df.Filter("myFilter(x)").Sum("y")
53print(sum.GetValue())
54~~~
55
56A more thorough explanation of how to use C++ code from Python can be found in the [PyROOT manual](https://root.cern/manual/python/#loading-user-libraries-and-just-in-time-compilation-jitting).
57
58#### Python code
59
60ROOT also offers the option to compile Python functions with fundamental types and arrays thereof using [Numba](https://numba.pydata.org/).
61Such compiled functions can then be used in a C++ expression provided to RDataFrame.
62
63The function to be compiled should be decorated with `ROOT.Numba.Declare`, which allows to specify the parameter and
64return types. See the following snippet for a simple example or the full tutorial [here](pyroot004__NumbaDeclare_8py.html).
65
66~~~{.py}
67@ROOT.Numba.Declare(["float"], "bool")
68def myFilter(x):
69 return x > 10
70
71df = ROOT.RDataFrame("myTree", "myFile.root")
72sum = df.Filter("Numba::myFilter(x)").Sum("y")
73print(sum.GetValue())
74~~~
75
76It also works with collections: `RVec` objects of fundamental types can be transparently converted to/from numpy arrays:
139The ROOT::RDF::AsRNode function casts an RDataFrame node to the generic ROOT::RDF::RNode type. From Python, it can be used to pass any RDataFrame node as an argument of a C++ function, as shown below: