Issue 1:
{Python 2.6.6, pandas 0.12}

A DataFrame will fail to unstack() when one of the columns retained as an index has NaN values. The code below sets up a dataframe with NaN in some index entries, at which point calling unstack() will fail.

In the first failure, the exception message is that the index "has duplicate entries" which is patently false. In the second failure, where a given id only has one NaN, the error message becomes cannot convert float NaN to integer.

A final try, with NaN converted to a sentinel value of 42, shows proper behavior.

import pandas
from numpy import nan

df = pandas.DataFrame(
{'agent': {
17263: 'Hg',
17264: 'U',
17265: 'Pb',
17266: 'Sn',
17267: 'Ag',
17268: 'Hg'},
'change': {
17263: nan,
17264: 0.0,
17265: 7.070e-06,
17266: 2.3614e-05,
17267: 0.0,
17268: -0.00015},
'dosage': {
17263: nan,
17264: nan,
17265: nan,
17266: 0.0133,
17267: 0.0133,
17268: 0.0133},
's_id': {
17263: 680585148,
17264: 680585148,
17265: 680585148,
17266: 680607017,
17267: 680607017,
17268: 680607017}}
)
try:
dupe = df.copy().set_index(['s_id','dosage','agent'])
badDupe = dupe.unstack()
except Exception as e:
print( 'Error with all data was: %s'%(e,) )
try:
getnan = df.ix[17264:].copy().set_index(['s_id','dosage','agent'])
badNan = getnan.unstack()
except Exception as e:
print( 'Error dropping first entry was: %s'%(e,) )
df.dosage[:3]=42
willWork = df.copy().set_index(['s_id','dosage','agent'])
u = willWork.unstack()
print(u)

Overall output:

Error with all data was: Index contains duplicate entries, cannot reshape
Error dropping first entry was: cannot convert float NaN to integer

change
agent Ag Hg Pb Sn U
s_id dosage
680585148 42.0000 NaN NaN 0.000007 NaN 0
680607017 0.0133 0 -0.00015 NaN 0.000024 NaN

Issue 2:
Add the following function to pd. dataFrame and pd.Series

def ends(df, x=5):
"""Returns both head and tail of the dataframe or series.

Args:
x (int): Optional number of rows to return for each head and tail
"""
print('{} rows x {} columns'.format(np.shape(df)[0],np.shape(df)[1]))
return df.head(x).append(df.tail(x))

Problem description

Often both the beginning and end of a df are of interest, fore example in a time series.

This leads to calling df.head() df.tail() in two seperate notebook cells. This is not only tedious, but also leads to a cluttered notebook. A function that returns both of these + a print on the number of rows and columns, thus allowing a check if the index matches the number of rows.

Example

import pandas as pd
import numpy as np
df = pd.DataFrame(np.random.rand(1500,6))
print(ends(df,2))

1500 rows x 6 columns

0
1
2
3
4
5

0
0.949695
0.160928
0.434134
0.943103
0.477830
0.903479

1
0.736711
0.103746
0.028694
0.205910
0.226061
0.458452

1498
0.362950
0.586887
0.399681
0.115366
0.239049
0.386281

1499
0.018102
0.852198
0.880993
0.671604
0.705586
0.802237

Output of pd.show_versions()

INSTALLED VERSIONS

commit: None

python: 3.6.2.final.0

python-bits: 64

OS: Windows

OS-release: 8.1

machine: AMD64

processor: Intel64 Family 6 Model 61 Stepping 4, GenuineIntel

byteorder: little

LC_ALL: None

LANG: None

LOCALE: None.None

pandas: 0.21.0

pytest: 3.3.1

pip: 9.0.1

setuptools: 38.2.4

Cython: 0.26.1

numpy: 1.12.1

scipy: 0.19.1

pyarrow: None

xarray: None

IPython: 6.1.0

sphinx: 1.6.3

patsy: 0.4.1

dateutil: 2.6.1

pytz: 2017.3

blosc: None

bottleneck: 1.2.1

tables: 3.4.2

numexpr: 2.6.2

feather: None

matplotlib: 2.0.2

openpyxl: 2.4.8

xlrd: 1.1.0

xlwt: 1.3.0

xlsxwriter: 0.9.8

lxml: 3.8.0

bs4: 4.6.0

html5lib: 0.999999999

sqlalchemy: 1.1.13

pymysql: None

psycopg2: None

jinja2: 2.10

s3fs: None

fastparquet: None

pandas_gbq: None

pandas_datareader: None