diff --git a/dfply/summarize.py b/dfply/summarize.py index 6afaf2e..3c15497 100644 --- a/dfply/summarize.py +++ b/dfply/summarize.py @@ -2,7 +2,17 @@ @dfpipe -def summarize(df, **kwargs): +def summarize(df, *args, **kwargs): + for e, v in enumerate(args): + column_name = "unnamed_arg_{}".format(e) + if column_name not in kwargs: + kwargs[column_name] = v + else: + raise KeyError( + "Positional argument {} was assigned " + "name '{}', which was also supplied as " + "a keyword argument.".format(e, column_name) + ) return pd.DataFrame({k: [v] for k, v in kwargs.items()}) diff --git a/test/test_summarize.py b/test/test_summarize.py index 2b50e24..737b120 100644 --- a/test/test_summarize.py +++ b/test/test_summarize.py @@ -24,6 +24,28 @@ def test_summarize(): summarize(price_mean=X.price.mean(), price_std=X.price.std())) +def test_summarize_with_positional_args(): + with_args = diamonds >> summarize( + X.price.mean(), + price_std=X.price.std() + ) >> rename( + price_mean=X.unnamed_arg_0 + ) + + with_kwargs = diamonds >> summarize( + price_std=X.price.std(), + price_mean=X.price.mean() + ) + + # Use `sort_index()` to account for + # Python versions < 3.6 which do not + # reliably conserve dictionary insertion order. + pd.testing.assert_frame_equal( + with_kwargs.sort_index(axis=1), + with_args.sort_index(axis=1) + ) + + def test_summarize_each(): to_match = pd.DataFrame({ 'price_mean':[np.mean(diamonds.price)],