We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
Nested transformations don't work
Transformations containing other transformations are not currently possible. They'll be implemented in #568. Here's an example of something that will work after that PR:

``` python
d = {'timestamp': [1379613528, 1379620047], 'platform': ["Linux", "Windows"]}
df = DataFrame(d)
t = TableSymbol('t', discover(df))
t = transform(t, timestamp=t.timestamp.map(datetime.fromtimestamp,
                                            schema='{timestamp: datetime}'))
expr = transform(t, date=t.timestamp.map(lambda x: x.date(),
                                            schema='{date: datetime}'))
result = compute(expr, df)
df['timestamp'] = df.timestamp.map(datetime.fromtimestamp)
df['date'] = df.timestamp.map(lambda x: x.date())
assert str(result) == str(df)
```


--- END ISSUE ---

Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
--- BEGIN FILES ---
Path: `blaze/compute/pandas.py`
Content:
```
1 """
2 
3 >>> from blaze.expr.table import TableSymbol
4 >>> from blaze.compute.pandas import compute
5 
6 >>> accounts = TableSymbol('accounts', '{name: string, amount: int}')
7 >>> deadbeats = accounts[accounts['amount'] < 0]['name']
8 
9 >>> from pandas import DataFrame
10 >>> data = [['Alice', 100], ['Bob', -50], ['Charlie', -20]]
11 >>> df = DataFrame(data, columns=['name', 'amount'])
12 >>> compute(deadbeats, df)
13 1        Bob
14 2    Charlie
15 Name: name, dtype: object
16 """
17 from __future__ import absolute_import, division, print_function
18 
19 import pandas as pd
20 from pandas.core.generic import NDFrame
21 from pandas import DataFrame, Series
22 from pandas.core.groupby import DataFrameGroupBy, SeriesGroupBy
23 import numpy as np
24 from collections import defaultdict
25 
26 from ..api.into import into
27 from ..dispatch import dispatch
28 from ..expr import (Projection, Column, Sort, Head, ColumnWise, Selection,
29                     Reduction, Distinct, Join, By, Summary, Label, ReLabel,
30                     Map, Apply, Merge, Union, TableExpr)
31 from ..expr import UnaryOp, BinOp
32 from ..expr import TableSymbol, common_subexpression
33 from .core import compute, compute_one, base
34 
35 __all__ = []
36 
37 
38 @dispatch(Projection, DataFrame)
39 def compute_one(t, df, **kwargs):
40     return df[list(t.columns)]
41 
42 
43 @dispatch(Column, (DataFrame, DataFrameGroupBy))
44 def compute_one(t, df, **kwargs):
45     return df[t.columns[0]]
46 
47 
48 @dispatch(Column, (Series, SeriesGroupBy))
49 def compute_one(_, s, **kwargs):
50     return s
51 
52 
53 @dispatch(ColumnWise, DataFrame)
54 def compute_one(t, df, **kwargs):
55     d = dict((t.child[c].scalar_symbol, df[c]) for c in t.child.columns)
56     return compute(t.expr, d)
57 
58 
59 @dispatch(ColumnWise, Series)
60 def compute_one(t, s, **kwargs):
61     return compute_one(t, s.to_frame(), **kwargs)
62 
63 
64 @dispatch(BinOp, Series, (Series, base))
65 def compute_one(t, lhs, rhs, **kwargs):
66     return t.op(lhs, rhs)
67 
68 
69 @dispatch(BinOp, (Series, base), Series)
70 def compute_one(t, lhs, rhs, **kwargs):
71     return t.op(lhs, rhs)
72 
73 
74 @dispatch(UnaryOp, NDFrame)
75 def compute_one(t, df, **kwargs):
76     f = getattr(t, 'op', getattr(np, t.symbol, None))
77     if f is None:
78         raise ValueError('%s is not a valid operation on %s objects' %
79                          (t.symbol, type(df).__name__))
80     return f(df)
81 
82 
83 @dispatch(Selection, (Series, DataFrame))
84 def compute_one(t, df, **kwargs):
85     predicate = compute(t.predicate, {t.child: df})
86     return df[predicate]
87 
88 
89 @dispatch(TableSymbol, DataFrame)
90 def compute_one(t, df, **kwargs):
91     if not list(t.columns) == list(df.columns):
92         # TODO also check dtype
93         raise ValueError("Schema mismatch: \n\nTable:\n%s\n\nDataFrame:\n%s"
94                          % (t, df))
95     return df
96 
97 
98 @dispatch(Join, DataFrame, DataFrame)
99 def compute_one(t, lhs, rhs, **kwargs):
100     """ Join two pandas data frames on arbitrary columns
101 
102     The approach taken here could probably be improved.
103 
104     To join on two columns we force each column to be the index of the
105     dataframe, perform the join, and then reset the index back to the left
106     side's original index.
107     """
108     result = pd.merge(lhs, rhs,
109                       left_on=t.on_left, right_on=t.on_right,
110                       how=t.how)
111     return result.reset_index()[t.columns]
112 
113 
114 @dispatch(TableSymbol, (DataFrameGroupBy, SeriesGroupBy))
115 def compute_one(t, gb, **kwargs):
116     return gb
117 
118 
119 @dispatch(Reduction, (DataFrame, DataFrameGroupBy))
120 def compute_one(t, df, **kwargs):
121     return getattr(df, t.symbol)()
122 
123 
124 @dispatch(Reduction, (SeriesGroupBy, Series))
125 def compute_one(t, s, **kwargs):
126     result = getattr(s, t.symbol)()
127 
128     # pandas may return an int, numpy scalar or non scalar here so we need to
129     # program defensively so that things are JSON serializable
130     try:
131         return result.item()
132     except (AttributeError, ValueError):
133         return result
134 
135 
136 @dispatch(Distinct, DataFrame)
137 def compute_one(t, df, **kwargs):
138     return df.drop_duplicates()
139 
140 
141 @dispatch(Distinct, Series)
142 def compute_one(t, s, **kwargs):
143     s2 = Series(s.unique())
144     s2.name = s.name
145     return s2
146 
147 
148 def unpack(seq):
149     """ Unpack sequence of length one
150 
151     >>> unpack([1, 2, 3])
152     [1, 2, 3]
153 
154     >>> unpack([1])
155     1
156     """
157     seq = list(seq)
158     if len(seq) == 1:
159         seq = seq[0]
160     return seq
161 
162 
163 Grouper = Column, ColumnWise, Series, list
164 
165 
166 @dispatch(By, list, DataFrame)
167 def get_grouper(c, grouper, df):
168     return grouper
169 
170 
171 @dispatch(By, (Column, ColumnWise, Series), NDFrame)
172 def get_grouper(c, grouper, df):
173     return compute(grouper, {c.child: df})
174 
175 
176 @dispatch(By, Projection, NDFrame)
177 def get_grouper(c, grouper, df):
178     return grouper.columns
179 
180 
181 @dispatch(By, Reduction, Grouper, NDFrame)
182 def compute_by(t, r, g, df):
183     names = r.dshape[0].names
184     preapply = compute(r.child, {t.child: df})
185 
186     # Pandas and Blaze column naming schemes differ
187     # Coerce DataFrame column names to match Blaze's names
188     preapply = preapply.copy()
189     if isinstance(preapply, Series):
190         preapply.name = names[0]
191     else:
192         preapply.columns = names
193     group_df = concat_nodup(df, preapply)
194 
195     gb = group_df.groupby(g)
196     groups = gb[names[0] if t.apply.child.iscolumn else names]
197 
198     return compute_one(r, groups)  # do reduction
199 
200 
201 @dispatch(By, Summary, Grouper, NDFrame)
202 def compute_by(t, s, g, df):
203     names = s.names
204     preapply = DataFrame(dict(zip(names,
205                                   (compute(v.child, {t.child: df})
206                                    for v in s.values))))
207 
208     df2 = concat_nodup(df, preapply)
209 
210     groups = df2.groupby(g)
211 
212     d = defaultdict(list)
213     for name, v in zip(names, s.values):
214         d[name].append(getattr(Series, v.symbol))
215 
216     result = groups.agg(dict(d))
217 
218     # Rearrange columns to match names order
219     result = result[sorted(result.columns, key=lambda t: names.index(t[0]))]
220     result.columns = t.apply.names  # flatten down multiindex
221     return result
222 
223 
224 @dispatch(TableExpr, DataFrame)
225 def post_compute_by(t, df):
226     return df.reset_index(drop=True)
227 
228 
229 @dispatch((Summary, Reduction), DataFrame)
230 def post_compute_by(t, df):
231     return df.reset_index()
232 
233 
234 @dispatch(By, NDFrame)
235 def compute_one(t, df, **kwargs):
236     grouper = get_grouper(t, t.grouper, df)
237     result = compute_by(t, t.apply, grouper, df)
238     return post_compute_by(t.apply, into(DataFrame, result))
239 
240 
241 def concat_nodup(a, b):
242     """ Concatenate two dataframes/series without duplicately named columns
243 
244 
245     >>> df = DataFrame([[1, 'Alice',   100],
246     ...                 [2, 'Bob',    -200],
247     ...                 [3, 'Charlie', 300]],
248     ...                columns=['id','name', 'amount'])
249 
250     >>> concat_nodup(df, df)
251        id     name  amount
252     0   1    Alice     100
253     1   2      Bob    -200
254     2   3  Charlie     300
255 
256 
257     >>> concat_nodup(df.name, df.amount)
258           name  amount
259     0    Alice     100
260     1      Bob    -200
261     2  Charlie     300
262 
263 
264 
265     >>> concat_nodup(df, df.amount + df.id)
266        id     name  amount    0
267     0   1    Alice     100  101
268     1   2      Bob    -200 -198
269     2   3  Charlie     300  303
270     """
271 
272     if isinstance(a, DataFrame) and isinstance(b, DataFrame):
273         return pd.concat([a, b[[c for c in b.columns if c not in a.columns]]],
274                          axis=1)
275     if isinstance(a, DataFrame) and isinstance(b, Series):
276         if b.name not in a.columns:
277             return pd.concat([a, b], axis=1)
278         else:
279             return a
280     if isinstance(a, Series) and isinstance(b, DataFrame):
281         return pd.concat([a, b[[c for c in b.columns if c != a.name]]], axis=1)
282     if isinstance(a, Series) and isinstance(b, Series):
283         if a.name == b.name:
284             return a
285         else:
286             return pd.concat([a, b], axis=1)
287 
288 
289 @dispatch(Sort, DataFrame)
290 def compute_one(t, df, **kwargs):
291     return df.sort(t.key, ascending=t.ascending)
292 
293 
294 @dispatch(Sort, Series)
295 def compute_one(t, s, **kwargs):
296     return s.order(ascending=t.ascending)
297 
298 
299 @dispatch(Head, (Series, DataFrame))
300 def compute_one(t, df, **kwargs):
301     return df.head(t.n)
302 
303 
304 @dispatch(Label, DataFrame)
305 def compute_one(t, df, **kwargs):
306     return DataFrame(df, columns=[t.label])
307 
308 
309 @dispatch(Label, Series)
310 def compute_one(t, df, **kwargs):
311     return Series(df, name=t.label)
312 
313 
314 @dispatch(ReLabel, DataFrame)
315 def compute_one(t, df, **kwargs):
316     return df.rename(columns=dict(t.labels))
317 
318 
319 @dispatch(ReLabel, Series)
320 def compute_one(t, s, **kwargs):
321     labels = t.labels
322     if len(labels) > 1:
323         raise ValueError('You can only relabel a Series with a single name')
324     pair, = labels
325     _, replacement = pair
326     return Series(s, name=replacement)
327 
328 
329 @dispatch(Map, DataFrame)
330 def compute_one(t, df, **kwargs):
331     return df.apply(lambda tup: t.func(*tup), axis=1)
332 
333 
334 @dispatch(Map, Series)
335 def compute_one(t, df, **kwargs):
336     return df.map(t.func)
337 
338 
339 @dispatch(Apply, (Series, DataFrame))
340 def compute_one(t, df, **kwargs):
341     return t.func(df)
342 
343 
344 @dispatch(Merge, DataFrame)
345 def compute_one(t, df, **kwargs):
346     subexpression = common_subexpression(*t.children)
347     children = [compute(child, {subexpression: df}) for child in t.children]
348     return pd.concat(children, axis=1)
349 
350 
351 @dispatch(Union, DataFrame, tuple)
352 def compute_one(t, example, children, **kwargs):
353     return pd.concat(children, axis=0)
354 
355 
356 @dispatch(Summary, DataFrame)
357 def compute_one(expr, data, **kwargs):
358     return Series(dict(zip(expr.names, [compute(val, {expr.child: data})
359                                         for val in expr.values])))
360
```
--- END FILES ---

Please first localize the bug based on the issue statement, and then generate a patch according to the `git diff` format fenced by three backticks.

Here is an example:

```diff
diff --git a/examples/server_async.py b/examples/server_async.py
--- a/examples/server_async.py
+++ b/examples/server_async.py
@@ -313,4 +313,4 @@
 
 
 if __name__ == "__main__":
-    asyncio.run(run_async_server("."), debug=True)
+    asyncio.run(run_async_server(), debug=True)
diff --git a/examples/server_sync.py b/examples/server_sync.py
--- a/examples/server_sync.py
+++ b/examples/server_sync.py
@@ -313,5 +313,5 @@
 
 
 if __name__ == "__main__":
-    server = run_sync_server(".")
+    server = run_sync_server()
     server.shutdown()

```

diff --git a/blaze/compute/pandas.py b/blaze/compute/pandas.py
--- a/blaze/compute/pandas.py
+++ b/blaze/compute/pandas.py
@@ -22,6 +22,7 @@
 from pandas.core.groupby import DataFrameGroupBy, SeriesGroupBy
 import numpy as np
 from collections import defaultdict
+from toolz import merge as merge_dicts
 
 from ..api.into import into
 from ..dispatch import dispatch
@@ -333,7 +334,13 @@
 
 @dispatch(Map, Series)
 def compute_one(t, df, **kwargs):
-    return df.map(t.func)
+    result = df.map(t.func)
+    try:
+        result.name = t.name
+    except NotImplementedError:
+        # We don't have a schema, but we should still be able to map
+        result.name = df.name
+    return result
 
 
 @dispatch(Apply, (Series, DataFrame))
@@ -341,10 +348,11 @@
     return t.func(df)
 
 
-@dispatch(Merge, DataFrame)
-def compute_one(t, df, **kwargs):
+@dispatch(Merge, NDFrame)
+def compute_one(t, df, scope=None, **kwargs):
     subexpression = common_subexpression(*t.children)
-    children = [compute(child, {subexpression: df}) for child in t.children]
+    scope = merge_dicts(scope or {}, {subexpression: df})
+    children = [compute(child, scope) for child in t.children]
     return pd.concat(children, axis=1)

{"golden_diff": "diff --git a/blaze/compute/pandas.py b/blaze/compute/pandas.py\n--- a/blaze/compute/pandas.py\n+++ b/blaze/compute/pandas.py\n@@ -22,6 +22,7 @@\n from pandas.core.groupby import DataFrameGroupBy, SeriesGroupBy\n import numpy as np\n from collections import defaultdict\n+from toolz import merge as merge_dicts\n \n from ..api.into import into\n from ..dispatch import dispatch\n@@ -333,7 +334,13 @@\n \n @dispatch(Map, Series)\n def compute_one(t, df, **kwargs):\n-    return df.map(t.func)\n+    result = df.map(t.func)\n+    try:\n+        result.name = t.name\n+    except NotImplementedError:\n+        # We don't have a schema, but we should still be able to map\n+        result.name = df.name\n+    return result\n \n \n @dispatch(Apply, (Series, DataFrame))\n@@ -341,10 +348,11 @@\n     return t.func(df)\n \n \n-@dispatch(Merge, DataFrame)\n-def compute_one(t, df, **kwargs):\n+@dispatch(Merge, NDFrame)\n+def compute_one(t, df, scope=None, **kwargs):\n     subexpression = common_subexpression(*t.children)\n-    children = [compute(child, {subexpression: df}) for child in t.children]\n+    scope = merge_dicts(scope or {}, {subexpression: df})\n+    children = [compute(child, scope) for child in t.children]\n     return pd.concat(children, axis=1)\n", "issue": "Nested transformations don't work\nTransformations containing other transformations are not currently possible. They'll be implemented in #568. Here's an example of something that will work after that PR:\n\n``` python\nd = {'timestamp': [1379613528, 1379620047], 'platform': [\"Linux\", \"Windows\"]}\ndf = DataFrame(d)\nt = TableSymbol('t', discover(df))\nt = transform(t, timestamp=t.timestamp.map(datetime.fromtimestamp,\n                                            schema='{timestamp: datetime}'))\nexpr = transform(t, date=t.timestamp.map(lambda x: x.date(),\n                                            schema='{date: datetime}'))\nresult = compute(expr, df)\ndf['timestamp'] = df.timestamp.map(datetime.fromtimestamp)\ndf['date'] = df.timestamp.map(lambda x: x.date())\nassert str(result) == str(df)\n```\n\n", "before_files": [{"content": "\"\"\"\n\n>>> from blaze.expr.table import TableSymbol\n>>> from blaze.compute.pandas import compute\n\n>>> accounts = TableSymbol('accounts', '{name: string, amount: int}')\n>>> deadbeats = accounts[accounts['amount'] < 0]['name']\n\n>>> from pandas import DataFrame\n>>> data = [['Alice', 100], ['Bob', -50], ['Charlie', -20]]\n>>> df = DataFrame(data, columns=['name', 'amount'])\n>>> compute(deadbeats, df)\n1        Bob\n2    Charlie\nName: name, dtype: object\n\"\"\"\nfrom __future__ import absolute_import, division, print_function\n\nimport pandas as pd\nfrom pandas.core.generic import NDFrame\nfrom pandas import DataFrame, Series\nfrom pandas.core.groupby import DataFrameGroupBy, SeriesGroupBy\nimport numpy as np\nfrom collections import defaultdict\n\nfrom ..api.into import into\nfrom ..dispatch import dispatch\nfrom ..expr import (Projection, Column, Sort, Head, ColumnWise, Selection,\n                    Reduction, Distinct, Join, By, Summary, Label, ReLabel,\n                    Map, Apply, Merge, Union, TableExpr)\nfrom ..expr import UnaryOp, BinOp\nfrom ..expr import TableSymbol, common_subexpression\nfrom .core import compute, compute_one, base\n\n__all__ = []\n\n\n@dispatch(Projection, DataFrame)\ndef compute_one(t, df, **kwargs):\n    return df[list(t.columns)]\n\n\n@dispatch(Column, (DataFrame, DataFrameGroupBy))\ndef compute_one(t, df, **kwargs):\n    return df[t.columns[0]]\n\n\n@dispatch(Column, (Series, SeriesGroupBy))\ndef compute_one(_, s, **kwargs):\n    return s\n\n\n@dispatch(ColumnWise, DataFrame)\ndef compute_one(t, df, **kwargs):\n    d = dict((t.child[c].scalar_symbol, df[c]) for c in t.child.columns)\n    return compute(t.expr, d)\n\n\n@dispatch(ColumnWise, Series)\ndef compute_one(t, s, **kwargs):\n    return compute_one(t, s.to_frame(), **kwargs)\n\n\n@dispatch(BinOp, Series, (Series, base))\ndef compute_one(t, lhs, rhs, **kwargs):\n    return t.op(lhs, rhs)\n\n\n@dispatch(BinOp, (Series, base), Series)\ndef compute_one(t, lhs, rhs, **kwargs):\n    return t.op(lhs, rhs)\n\n\n@dispatch(UnaryOp, NDFrame)\ndef compute_one(t, df, **kwargs):\n    f = getattr(t, 'op', getattr(np, t.symbol, None))\n    if f is None:\n        raise ValueError('%s is not a valid operation on %s objects' %\n                         (t.symbol, type(df).__name__))\n    return f(df)\n\n\n@dispatch(Selection, (Series, DataFrame))\ndef compute_one(t, df, **kwargs):\n    predicate = compute(t.predicate, {t.child: df})\n    return df[predicate]\n\n\n@dispatch(TableSymbol, DataFrame)\ndef compute_one(t, df, **kwargs):\n    if not list(t.columns) == list(df.columns):\n        # TODO also check dtype\n        raise ValueError(\"Schema mismatch: \\n\\nTable:\\n%s\\n\\nDataFrame:\\n%s\"\n                         % (t, df))\n    return df\n\n\n@dispatch(Join, DataFrame, DataFrame)\ndef compute_one(t, lhs, rhs, **kwargs):\n    \"\"\" Join two pandas data frames on arbitrary columns\n\n    The approach taken here could probably be improved.\n\n    To join on two columns we force each column to be the index of the\n    dataframe, perform the join, and then reset the index back to the left\n    side's original index.\n    \"\"\"\n    result = pd.merge(lhs, rhs,\n                      left_on=t.on_left, right_on=t.on_right,\n                      how=t.how)\n    return result.reset_index()[t.columns]\n\n\n@dispatch(TableSymbol, (DataFrameGroupBy, SeriesGroupBy))\ndef compute_one(t, gb, **kwargs):\n    return gb\n\n\n@dispatch(Reduction, (DataFrame, DataFrameGroupBy))\ndef compute_one(t, df, **kwargs):\n    return getattr(df, t.symbol)()\n\n\n@dispatch(Reduction, (SeriesGroupBy, Series))\ndef compute_one(t, s, **kwargs):\n    result = getattr(s, t.symbol)()\n\n    # pandas may return an int, numpy scalar or non scalar here so we need to\n    # program defensively so that things are JSON serializable\n    try:\n        return result.item()\n    except (AttributeError, ValueError):\n        return result\n\n\n@dispatch(Distinct, DataFrame)\ndef compute_one(t, df, **kwargs):\n    return df.drop_duplicates()\n\n\n@dispatch(Distinct, Series)\ndef compute_one(t, s, **kwargs):\n    s2 = Series(s.unique())\n    s2.name = s.name\n    return s2\n\n\ndef unpack(seq):\n    \"\"\" Unpack sequence of length one\n\n    >>> unpack([1, 2, 3])\n    [1, 2, 3]\n\n    >>> unpack([1])\n    1\n    \"\"\"\n    seq = list(seq)\n    if len(seq) == 1:\n        seq = seq[0]\n    return seq\n\n\nGrouper = Column, ColumnWise, Series, list\n\n\n@dispatch(By, list, DataFrame)\ndef get_grouper(c, grouper, df):\n    return grouper\n\n\n@dispatch(By, (Column, ColumnWise, Series), NDFrame)\ndef get_grouper(c, grouper, df):\n    return compute(grouper, {c.child: df})\n\n\n@dispatch(By, Projection, NDFrame)\ndef get_grouper(c, grouper, df):\n    return grouper.columns\n\n\n@dispatch(By, Reduction, Grouper, NDFrame)\ndef compute_by(t, r, g, df):\n    names = r.dshape[0].names\n    preapply = compute(r.child, {t.child: df})\n\n    # Pandas and Blaze column naming schemes differ\n    # Coerce DataFrame column names to match Blaze's names\n    preapply = preapply.copy()\n    if isinstance(preapply, Series):\n        preapply.name = names[0]\n    else:\n        preapply.columns = names\n    group_df = concat_nodup(df, preapply)\n\n    gb = group_df.groupby(g)\n    groups = gb[names[0] if t.apply.child.iscolumn else names]\n\n    return compute_one(r, groups)  # do reduction\n\n\n@dispatch(By, Summary, Grouper, NDFrame)\ndef compute_by(t, s, g, df):\n    names = s.names\n    preapply = DataFrame(dict(zip(names,\n                                  (compute(v.child, {t.child: df})\n                                   for v in s.values))))\n\n    df2 = concat_nodup(df, preapply)\n\n    groups = df2.groupby(g)\n\n    d = defaultdict(list)\n    for name, v in zip(names, s.values):\n        d[name].append(getattr(Series, v.symbol))\n\n    result = groups.agg(dict(d))\n\n    # Rearrange columns to match names order\n    result = result[sorted(result.columns, key=lambda t: names.index(t[0]))]\n    result.columns = t.apply.names  # flatten down multiindex\n    return result\n\n\n@dispatch(TableExpr, DataFrame)\ndef post_compute_by(t, df):\n    return df.reset_index(drop=True)\n\n\n@dispatch((Summary, Reduction), DataFrame)\ndef post_compute_by(t, df):\n    return df.reset_index()\n\n\n@dispatch(By, NDFrame)\ndef compute_one(t, df, **kwargs):\n    grouper = get_grouper(t, t.grouper, df)\n    result = compute_by(t, t.apply, grouper, df)\n    return post_compute_by(t.apply, into(DataFrame, result))\n\n\ndef concat_nodup(a, b):\n    \"\"\" Concatenate two dataframes/series without duplicately named columns\n\n\n    >>> df = DataFrame([[1, 'Alice',   100],\n    ...                 [2, 'Bob',    -200],\n    ...                 [3, 'Charlie', 300]],\n    ...                columns=['id','name', 'amount'])\n\n    >>> concat_nodup(df, df)\n       id     name  amount\n    0   1    Alice     100\n    1   2      Bob    -200\n    2   3  Charlie     300\n\n\n    >>> concat_nodup(df.name, df.amount)\n          name  amount\n    0    Alice     100\n    1      Bob    -200\n    2  Charlie     300\n\n\n\n    >>> concat_nodup(df, df.amount + df.id)\n       id     name  amount    0\n    0   1    Alice     100  101\n    1   2      Bob    -200 -198\n    2   3  Charlie     300  303\n    \"\"\"\n\n    if isinstance(a, DataFrame) and isinstance(b, DataFrame):\n        return pd.concat([a, b[[c for c in b.columns if c not in a.columns]]],\n                         axis=1)\n    if isinstance(a, DataFrame) and isinstance(b, Series):\n        if b.name not in a.columns:\n            return pd.concat([a, b], axis=1)\n        else:\n            return a\n    if isinstance(a, Series) and isinstance(b, DataFrame):\n        return pd.concat([a, b[[c for c in b.columns if c != a.name]]], axis=1)\n    if isinstance(a, Series) and isinstance(b, Series):\n        if a.name == b.name:\n            return a\n        else:\n            return pd.concat([a, b], axis=1)\n\n\n@dispatch(Sort, DataFrame)\ndef compute_one(t, df, **kwargs):\n    return df.sort(t.key, ascending=t.ascending)\n\n\n@dispatch(Sort, Series)\ndef compute_one(t, s, **kwargs):\n    return s.order(ascending=t.ascending)\n\n\n@dispatch(Head, (Series, DataFrame))\ndef compute_one(t, df, **kwargs):\n    return df.head(t.n)\n\n\n@dispatch(Label, DataFrame)\ndef compute_one(t, df, **kwargs):\n    return DataFrame(df, columns=[t.label])\n\n\n@dispatch(Label, Series)\ndef compute_one(t, df, **kwargs):\n    return Series(df, name=t.label)\n\n\n@dispatch(ReLabel, DataFrame)\ndef compute_one(t, df, **kwargs):\n    return df.rename(columns=dict(t.labels))\n\n\n@dispatch(ReLabel, Series)\ndef compute_one(t, s, **kwargs):\n    labels = t.labels\n    if len(labels) > 1:\n        raise ValueError('You can only relabel a Series with a single name')\n    pair, = labels\n    _, replacement = pair\n    return Series(s, name=replacement)\n\n\n@dispatch(Map, DataFrame)\ndef compute_one(t, df, **kwargs):\n    return df.apply(lambda tup: t.func(*tup), axis=1)\n\n\n@dispatch(Map, Series)\ndef compute_one(t, df, **kwargs):\n    return df.map(t.func)\n\n\n@dispatch(Apply, (Series, DataFrame))\ndef compute_one(t, df, **kwargs):\n    return t.func(df)\n\n\n@dispatch(Merge, DataFrame)\ndef compute_one(t, df, **kwargs):\n    subexpression = common_subexpression(*t.children)\n    children = [compute(child, {subexpression: df}) for child in t.children]\n    return pd.concat(children, axis=1)\n\n\n@dispatch(Union, DataFrame, tuple)\ndef compute_one(t, example, children, **kwargs):\n    return pd.concat(children, axis=0)\n\n\n@dispatch(Summary, DataFrame)\ndef compute_one(expr, data, **kwargs):\n    return Series(dict(zip(expr.names, [compute(val, {expr.child: data})\n                                        for val in expr.values])))\n", "path": "blaze/compute/pandas.py"}], "after_files": [{"content": "\"\"\"\n\n>>> from blaze.expr.table import TableSymbol\n>>> from blaze.compute.pandas import compute\n\n>>> accounts = TableSymbol('accounts', '{name: string, amount: int}')\n>>> deadbeats = accounts[accounts['amount'] < 0]['name']\n\n>>> from pandas import DataFrame\n>>> data = [['Alice', 100], ['Bob', -50], ['Charlie', -20]]\n>>> df = DataFrame(data, columns=['name', 'amount'])\n>>> compute(deadbeats, df)\n1        Bob\n2    Charlie\nName: name, dtype: object\n\"\"\"\nfrom __future__ import absolute_import, division, print_function\n\nimport pandas as pd\nfrom pandas.core.generic import NDFrame\nfrom pandas import DataFrame, Series\nfrom pandas.core.groupby import DataFrameGroupBy, SeriesGroupBy\nimport numpy as np\nfrom collections import defaultdict\nfrom toolz import merge as merge_dicts\n\nfrom ..api.into import into\nfrom ..dispatch import dispatch\nfrom ..expr import (Projection, Column, Sort, Head, ColumnWise, Selection,\n                    Reduction, Distinct, Join, By, Summary, Label, ReLabel,\n                    Map, Apply, Merge, Union, TableExpr)\nfrom ..expr import UnaryOp, BinOp\nfrom ..expr import TableSymbol, common_subexpression\nfrom .core import compute, compute_one, base\n\n__all__ = []\n\n\n@dispatch(Projection, DataFrame)\ndef compute_one(t, df, **kwargs):\n    return df[list(t.columns)]\n\n\n@dispatch(Column, (DataFrame, DataFrameGroupBy))\ndef compute_one(t, df, **kwargs):\n    return df[t.columns[0]]\n\n\n@dispatch(Column, (Series, SeriesGroupBy))\ndef compute_one(_, s, **kwargs):\n    return s\n\n\n@dispatch(ColumnWise, DataFrame)\ndef compute_one(t, df, **kwargs):\n    d = dict((t.child[c].scalar_symbol, df[c]) for c in t.child.columns)\n    return compute(t.expr, d)\n\n\n@dispatch(ColumnWise, Series)\ndef compute_one(t, s, **kwargs):\n    return compute_one(t, s.to_frame(), **kwargs)\n\n\n@dispatch(BinOp, Series, (Series, base))\ndef compute_one(t, lhs, rhs, **kwargs):\n    return t.op(lhs, rhs)\n\n\n@dispatch(BinOp, (Series, base), Series)\ndef compute_one(t, lhs, rhs, **kwargs):\n    return t.op(lhs, rhs)\n\n\n@dispatch(UnaryOp, NDFrame)\ndef compute_one(t, df, **kwargs):\n    f = getattr(t, 'op', getattr(np, t.symbol, None))\n    if f is None:\n        raise ValueError('%s is not a valid operation on %s objects' %\n                         (t.symbol, type(df).__name__))\n    return f(df)\n\n\n@dispatch(Selection, (Series, DataFrame))\ndef compute_one(t, df, **kwargs):\n    predicate = compute(t.predicate, {t.child: df})\n    return df[predicate]\n\n\n@dispatch(TableSymbol, DataFrame)\ndef compute_one(t, df, **kwargs):\n    if not list(t.columns) == list(df.columns):\n        # TODO also check dtype\n        raise ValueError(\"Schema mismatch: \\n\\nTable:\\n%s\\n\\nDataFrame:\\n%s\"\n                         % (t, df))\n    return df\n\n\n@dispatch(Join, DataFrame, DataFrame)\ndef compute_one(t, lhs, rhs, **kwargs):\n    \"\"\" Join two pandas data frames on arbitrary columns\n\n    The approach taken here could probably be improved.\n\n    To join on two columns we force each column to be the index of the\n    dataframe, perform the join, and then reset the index back to the left\n    side's original index.\n    \"\"\"\n    result = pd.merge(lhs, rhs,\n                      left_on=t.on_left, right_on=t.on_right,\n                      how=t.how)\n    return result.reset_index()[t.columns]\n\n\n@dispatch(TableSymbol, (DataFrameGroupBy, SeriesGroupBy))\ndef compute_one(t, gb, **kwargs):\n    return gb\n\n\n@dispatch(Reduction, (DataFrame, DataFrameGroupBy))\ndef compute_one(t, df, **kwargs):\n    return getattr(df, t.symbol)()\n\n\n@dispatch(Reduction, (SeriesGroupBy, Series))\ndef compute_one(t, s, **kwargs):\n    result = getattr(s, t.symbol)()\n\n    # pandas may return an int, numpy scalar or non scalar here so we need to\n    # program defensively so that things are JSON serializable\n    try:\n        return result.item()\n    except (AttributeError, ValueError):\n        return result\n\n\n@dispatch(Distinct, DataFrame)\ndef compute_one(t, df, **kwargs):\n    return df.drop_duplicates()\n\n\n@dispatch(Distinct, Series)\ndef compute_one(t, s, **kwargs):\n    s2 = Series(s.unique())\n    s2.name = s.name\n    return s2\n\n\ndef unpack(seq):\n    \"\"\" Unpack sequence of length one\n\n    >>> unpack([1, 2, 3])\n    [1, 2, 3]\n\n    >>> unpack([1])\n    1\n    \"\"\"\n    seq = list(seq)\n    if len(seq) == 1:\n        seq = seq[0]\n    return seq\n\n\nGrouper = Column, ColumnWise, Series, list\n\n\n@dispatch(By, list, DataFrame)\ndef get_grouper(c, grouper, df):\n    return grouper\n\n\n@dispatch(By, (Column, ColumnWise, Series), NDFrame)\ndef get_grouper(c, grouper, df):\n    return compute(grouper, {c.child: df})\n\n\n@dispatch(By, Projection, NDFrame)\ndef get_grouper(c, grouper, df):\n    return grouper.columns\n\n\n@dispatch(By, Reduction, Grouper, NDFrame)\ndef compute_by(t, r, g, df):\n    names = r.dshape[0].names\n    preapply = compute(r.child, {t.child: df})\n\n    # Pandas and Blaze column naming schemes differ\n    # Coerce DataFrame column names to match Blaze's names\n    preapply = preapply.copy()\n    if isinstance(preapply, Series):\n        preapply.name = names[0]\n    else:\n        preapply.columns = names\n    group_df = concat_nodup(df, preapply)\n\n    gb = group_df.groupby(g)\n    groups = gb[names[0] if t.apply.child.iscolumn else names]\n\n    return compute_one(r, groups)  # do reduction\n\n\n@dispatch(By, Summary, Grouper, NDFrame)\ndef compute_by(t, s, g, df):\n    names = s.names\n    preapply = DataFrame(dict(zip(names,\n                                  (compute(v.child, {t.child: df})\n                                   for v in s.values))))\n\n    df2 = concat_nodup(df, preapply)\n\n    groups = df2.groupby(g)\n\n    d = defaultdict(list)\n    for name, v in zip(names, s.values):\n        d[name].append(getattr(Series, v.symbol))\n\n    result = groups.agg(dict(d))\n\n    # Rearrange columns to match names order\n    result = result[sorted(result.columns, key=lambda t: names.index(t[0]))]\n    result.columns = t.apply.names  # flatten down multiindex\n    return result\n\n\n@dispatch(TableExpr, DataFrame)\ndef post_compute_by(t, df):\n    return df.reset_index(drop=True)\n\n\n@dispatch((Summary, Reduction), DataFrame)\ndef post_compute_by(t, df):\n    return df.reset_index()\n\n\n@dispatch(By, NDFrame)\ndef compute_one(t, df, **kwargs):\n    grouper = get_grouper(t, t.grouper, df)\n    result = compute_by(t, t.apply, grouper, df)\n    return post_compute_by(t.apply, into(DataFrame, result))\n\n\ndef concat_nodup(a, b):\n    \"\"\" Concatenate two dataframes/series without duplicately named columns\n\n\n    >>> df = DataFrame([[1, 'Alice',   100],\n    ...                 [2, 'Bob',    -200],\n    ...                 [3, 'Charlie', 300]],\n    ...                columns=['id','name', 'amount'])\n\n    >>> concat_nodup(df, df)\n       id     name  amount\n    0   1    Alice     100\n    1   2      Bob    -200\n    2   3  Charlie     300\n\n\n    >>> concat_nodup(df.name, df.amount)\n          name  amount\n    0    Alice     100\n    1      Bob    -200\n    2  Charlie     300\n\n\n\n    >>> concat_nodup(df, df.amount + df.id)\n       id     name  amount    0\n    0   1    Alice     100  101\n    1   2      Bob    -200 -198\n    2   3  Charlie     300  303\n    \"\"\"\n\n    if isinstance(a, DataFrame) and isinstance(b, DataFrame):\n        return pd.concat([a, b[[c for c in b.columns if c not in a.columns]]],\n                         axis=1)\n    if isinstance(a, DataFrame) and isinstance(b, Series):\n        if b.name not in a.columns:\n            return pd.concat([a, b], axis=1)\n        else:\n            return a\n    if isinstance(a, Series) and isinstance(b, DataFrame):\n        return pd.concat([a, b[[c for c in b.columns if c != a.name]]], axis=1)\n    if isinstance(a, Series) and isinstance(b, Series):\n        if a.name == b.name:\n            return a\n        else:\n            return pd.concat([a, b], axis=1)\n\n\n@dispatch(Sort, DataFrame)\ndef compute_one(t, df, **kwargs):\n    return df.sort(t.key, ascending=t.ascending)\n\n\n@dispatch(Sort, Series)\ndef compute_one(t, s, **kwargs):\n    return s.order(ascending=t.ascending)\n\n\n@dispatch(Head, (Series, DataFrame))\ndef compute_one(t, df, **kwargs):\n    return df.head(t.n)\n\n\n@dispatch(Label, DataFrame)\ndef compute_one(t, df, **kwargs):\n    return DataFrame(df, columns=[t.label])\n\n\n@dispatch(Label, Series)\ndef compute_one(t, df, **kwargs):\n    return Series(df, name=t.label)\n\n\n@dispatch(ReLabel, DataFrame)\ndef compute_one(t, df, **kwargs):\n    return df.rename(columns=dict(t.labels))\n\n\n@dispatch(ReLabel, Series)\ndef compute_one(t, s, **kwargs):\n    labels = t.labels\n    if len(labels) > 1:\n        raise ValueError('You can only relabel a Series with a single name')\n    pair, = labels\n    _, replacement = pair\n    return Series(s, name=replacement)\n\n\n@dispatch(Map, DataFrame)\ndef compute_one(t, df, **kwargs):\n    return df.apply(lambda tup: t.func(*tup), axis=1)\n\n\n@dispatch(Map, Series)\ndef compute_one(t, df, **kwargs):\n    result = df.map(t.func)\n    try:\n        result.name = t.name\n    except NotImplementedError:\n        # We don't have a schema, but we should still be able to map\n        result.name = df.name\n    return result\n\n\n@dispatch(Apply, (Series, DataFrame))\ndef compute_one(t, df, **kwargs):\n    return t.func(df)\n\n\n@dispatch(Merge, NDFrame)\ndef compute_one(t, df, scope=None, **kwargs):\n    subexpression = common_subexpression(*t.children)\n    scope = merge_dicts(scope or {}, {subexpression: df})\n    children = [compute(child, scope) for child in t.children]\n    return pd.concat(children, axis=1)\n\n\n@dispatch(Union, DataFrame, tuple)\ndef compute_one(t, example, children, **kwargs):\n    return pd.concat(children, axis=0)\n\n\n@dispatch(Summary, DataFrame)\ndef compute_one(expr, data, **kwargs):\n    return Series(dict(zip(expr.names, [compute(val, {expr.child: data})\n                                        for val in expr.values])))\n", "path": "blaze/compute/pandas.py"}]}