9
9
Any ,
10
10
)
11
11
12
+ from pandas .core .dtypes .common import is_scalar
13
+
12
14
from pandas .core .series import Series
13
15
14
16
if TYPE_CHECKING :
@@ -32,137 +34,105 @@ def __init__(self, func: Callable[[DataFrame], Any]) -> None:
32
34
33
35
def __call__ (self , df : DataFrame ) -> Series :
34
36
result = self ._func (df )
35
- if not isinstance (result , Series ):
37
+ if not ( isinstance (result , Series ) or is_scalar ( result ) ):
36
38
msg = (
37
- "Expected function which returns Series, "
39
+ "Expected function which returns Series or scalar , "
38
40
f"got function which returns: { type (result )} "
39
41
)
40
42
raise TypeError (msg )
41
43
return result
42
44
43
- # namespaces
44
- @property
45
- def dt (self ) -> NamespaceExpr :
46
- return NamespaceExpr (self , "dt" )
47
-
48
- @property
49
- def str (self ) -> NamespaceExpr :
50
- return NamespaceExpr (self , "str" )
51
-
52
- @property
53
- def cat (self ) -> NamespaceExpr :
54
- return NamespaceExpr (self , "cat" )
55
-
56
- @property
57
- def list (self ) -> NamespaceExpr :
58
- return NamespaceExpr (self , "list" )
59
-
60
- @property
61
- def sparse (self ) -> NamespaceExpr :
62
- return NamespaceExpr (self , "sparse" )
63
-
64
- @property
65
- def struct (self ) -> NamespaceExpr :
66
- return NamespaceExpr (self , "struct" )
45
+ def _with_binary_op (self , op : str , other : Any ) -> Expr :
46
+ if isinstance (other , Expr ):
47
+ return Expr (lambda df : getattr (self ._func (df ), op )(other ._func (df )))
48
+ return Expr (lambda df : getattr (self ._func (df ), op )(other ))
67
49
68
50
# Binary ops
69
-
70
51
def __add__ (self , other : Any ) -> Expr :
71
- if isinstance (other , Expr ):
72
- return Expr (lambda df : self ._func (df ).__add__ (other ._func (df )))
73
- return Expr (lambda df : self ._func (df ).__add__ (other ))
52
+ return self ._with_binary_op ("__add__" , other )
74
53
75
54
def __radd__ (self , other : Any ) -> Expr :
76
- if isinstance (other , Expr ):
77
- return Expr (lambda df : self ._func (df ).__radd__ (other ._func (df )))
78
- return Expr (lambda df : self ._func (df ).__radd__ (other ))
55
+ return self ._with_binary_op ("__radd__" , other )
79
56
80
57
def __sub__ (self , other : Any ) -> Expr :
81
- if isinstance (other , Expr ):
82
- return Expr (lambda df : self ._func (df ).__sub__ (other ._func (df )))
83
- return Expr (lambda df : self ._func (df ).__sub__ (other ))
58
+ return self ._with_binary_op ("__sub__" , other )
84
59
85
60
def __rsub__ (self , other : Any ) -> Expr :
86
- if isinstance (other , Expr ):
87
- return Expr (lambda df : self ._func (df ).__rsub__ (other ._func (df )))
88
- return Expr (lambda df : self ._func (df ).__rsub__ (other ))
61
+ return self ._with_binary_op ("__rsub__" , other )
89
62
90
63
def __mul__ (self , other : Any ) -> Expr :
91
- if isinstance (other , Expr ):
92
- return Expr (lambda df : self ._func (df ).__mul__ (other ._func (df )))
93
- return Expr (lambda df : self ._func (df ).__mul__ (other ))
64
+ return self ._with_binary_op ("__mul__" , other )
94
65
95
66
def __rmul__ (self , other : Any ) -> Expr :
96
- if isinstance (other , Expr ):
97
- return Expr (lambda df : self ._func (df ).__rmul__ (other ._func (df )))
98
- return Expr (lambda df : self ._func (df ).__rmul__ (other ))
67
+ return self ._with_binary_op ("__rmul__" , other )
99
68
100
69
def __truediv__ (self , other : Any ) -> Expr :
101
- if isinstance (other , Expr ):
102
- return Expr (lambda df : self ._func (df ).__truediv__ (other ._func (df )))
103
- return Expr (lambda df : self ._func (df ).__truediv__ (other ))
70
+ return self ._with_binary_op ("__truediv__" , other )
104
71
105
72
def __rtruediv__ (self , other : Any ) -> Expr :
106
- if isinstance (other , Expr ):
107
- return Expr (lambda df : self ._func (df ).__rtruediv__ (other ._func (df )))
108
- return Expr (lambda df : self ._func (df ).__rtruediv__ (other ))
73
+ return self ._with_binary_op ("__rtruediv__" , other )
109
74
110
75
def __floordiv__ (self , other : Any ) -> Expr :
111
- if isinstance (other , Expr ):
112
- return Expr (lambda df : self ._func (df ).__floordiv__ (other ._func (df )))
113
- return Expr (lambda df : self ._func (df ).__floordiv__ (other ))
76
+ return self ._with_binary_op ("__floordiv__" , other )
114
77
115
78
def __rfloordiv__ (self , other : Any ) -> Expr :
116
- if isinstance (other , Expr ):
117
- return Expr (lambda df : self ._func (df ).__rfloordiv__ (other ._func (df )))
118
- return Expr (lambda df : self ._func (df ).__rfloordiv__ (other ))
79
+ return self ._with_binary_op ("__rfloordiv__" , other )
119
80
120
81
def __ge__ (self , other : Any ) -> Expr :
121
- if isinstance (other , Expr ):
122
- return Expr (lambda df : self ._func (df ).__ge__ (other ._func (df )))
123
- return Expr (lambda df : self ._func (df ).__ge__ (other ))
82
+ return self ._with_binary_op ("__ge__" , other )
124
83
125
84
def __gt__ (self , other : Any ) -> Expr :
126
- if isinstance (other , Expr ):
127
- return Expr (lambda df : self ._func (df ).__gt__ (other ._func (df )))
128
- return Expr (lambda df : self ._func (df ).__gt__ (other ))
85
+ return self ._with_binary_op ("__gt__" , other )
129
86
130
87
def __le__ (self , other : Any ) -> Expr :
131
- if isinstance (other , Expr ):
132
- return Expr (lambda df : self ._func (df ).__le__ (other ._func (df )))
133
- return Expr (lambda df : self ._func (df ).__le__ (other ))
88
+ return self ._with_binary_op ("__le__" , other )
134
89
135
90
def __lt__ (self , other : Any ) -> Expr :
136
- if isinstance (other , Expr ):
137
- return Expr (lambda df : self ._func (df ).__lt__ (other ._func (df )))
138
- return Expr (lambda df : self ._func (df ).__lt__ (other ))
91
+ return self ._with_binary_op ("__lt__" , other )
139
92
140
93
def __eq__ (self , other : object ) -> Expr : # type: ignore[override]
141
- if isinstance (other , Expr ):
142
- return Expr (lambda df : self ._func (df ).__eq__ (other ._func (df )))
143
- return Expr (lambda df : self ._func (df ).__eq__ (other ))
94
+ return self ._with_binary_op ("__eq__" , other )
144
95
145
96
def __ne__ (self , other : object ) -> Expr : # type: ignore[override]
146
- if isinstance (other , Expr ):
147
- return Expr (lambda df : self ._func (df ).__ne__ (other ._func (df )))
148
- return Expr (lambda df : self ._func (df ).__ne__ (other ))
97
+ return self ._with_binary_op ("__ne__" , other )
149
98
150
99
def __mod__ (self , other : Any ) -> Expr :
151
- if isinstance (other , Expr ):
152
- return Expr (lambda df : self ._func (df ).__mod__ (other ._func (df )))
153
- return Expr (lambda df : self ._func (df ).__mod__ (other ))
100
+ return self ._with_binary_op ("__mod__" , other )
154
101
155
102
# Everything else
156
-
157
- # Function "pandas.core.col.Expr.str" is not valid as a type
158
- def __getattr__ (self , attr : str , / ) -> Any : # type: ignore[valid-type]
103
+ def __getattr__ (self , attr : str , / ) -> Callable [..., Expr ]:
159
104
def func (df : DataFrame , * args : Any , ** kwargs : Any ) -> Any :
160
105
parsed_args = parse_args (df , * args )
161
106
parsed_kwargs = parse_kwargs (df , ** kwargs )
162
107
return getattr (self (df ), attr )(* parsed_args , ** parsed_kwargs )
163
108
164
109
return lambda * args , ** kwargs : Expr (lambda df : func (df , * args , ** kwargs ))
165
110
111
+ # Namespaces
112
+ @property
113
+ def dt (self ) -> NamespaceExpr :
114
+ return NamespaceExpr (self , "dt" )
115
+
116
+ @property
117
+ def str (self ) -> NamespaceExpr :
118
+ return NamespaceExpr (self , "str" )
119
+
120
+ @property
121
+ def cat (self ) -> NamespaceExpr :
122
+ return NamespaceExpr (self , "cat" )
123
+
124
+ @property
125
+ def list (self ) -> NamespaceExpr :
126
+ return NamespaceExpr (self , "list" )
127
+
128
+ @property
129
+ def sparse (self ) -> NamespaceExpr :
130
+ return NamespaceExpr (self , "sparse" )
131
+
132
+ @property
133
+ def struct (self ) -> NamespaceExpr :
134
+ return NamespaceExpr (self , "struct" )
135
+
166
136
167
137
class NamespaceExpr :
168
138
def __init__ (self , func : Callable [[DataFrame ], Any ], namespace : str ) -> None :
0 commit comments