Issue 1:
Hi all,

I have a strange issue with pandas 0.9, I think it's a bug. I'm trying to use dataframe.join() and it works well on a random dataframe, but not on a dataframe created from my simulation result. The code below shows that join() on the second dataframe blows up the index and the result is completely wrong.

To run this code you need this file: https://dl.dropbox.com/u/6200325/mydf.dataframe in your work folder. The script below can also be downloaded here: https://dl.dropbox.com/u/6200325/BugJoin.py

This is the result I get:

In [17]: run -i 'C:\Workspace\Python\Tests\BugJoin.py'

Before:

<class 'pandas.core.frame.DataFrame'>

DatetimeIndex: 100000 entries, 2012-01-01 00:00:00 to 2023-05-29 15:00:00

Freq: H

Empty DataFrame

<class 'pandas.core.frame.DataFrame'>

DatetimeIndex: 100000 entries, 2012-01-01 00:00:00 to 2023-05-29 15:00:00

Freq: H

Data columns:

0 100000 non-null values

dtypes: float64(1)

After:

<class 'pandas.core.frame.DataFrame'>

DatetimeIndex: 100000 entries, 2012-01-01 00:00:00 to 2023-05-29 15:00:00

Freq: H

Data columns:

0 100000 non-null values

dtypes: float64(1)

Before:

<class 'pandas.core.frame.DataFrame'>

DatetimeIndex: 108355 entries, 2010-01-01 00:00:00 to 2011-01-01 00:00:00

Empty DataFrame

<class 'pandas.core.frame.DataFrame'>

DatetimeIndex: 108355 entries, 2010-01-01 00:00:00 to 2011-01-01 00:00:00

Data columns:

SID0000 108355 non-null values

dtypes: float64(1)

After:

<class 'pandas.core.frame.DataFrame'>

DatetimeIndex: 4054807 entries, 2010-01-09 16:00:00 to 2010-05-17 15:55:42

Data columns:

SID0000 4054807 non-null values

dtypes: float64(1)

This is the code from the script:

import numpy as np
import pandas as pd
from scipy.integrate import cumtrapz

df1=pd.DataFrame(np.random.rand(1e5),
index=pd.date_range('2012-01-01', freq='H', periods=1e5))

df2=pd.load('mydf.dataframe')

for dataframe in [df1, df2]:

cum = pd.DataFrame(index=dataframe.index)
for c in dataframe.columns:
# we need to remove the empty values for the cumtrapz function to work
ts = dataframe[c].dropna()

tscum = pd.DataFrame(data=cumtrapz(ts.values, ts.index.asi8/1e9, initial=0),
index=ts.index,
columns=[c])
print '\nBefore:'
print cum, '\n'
print tscum, '\n'

cum=cum.join(tscum, how='left')

print 'After:'
print cum

Issue 2:
I propose that itertuples() should return collections.namedtuple objects, a drop-in replacement for the standard tuple but with the benefit of having named fields. I have tested the following with Python 3.4 (only slight changes compared to the current implementation).

def itertuples(self, index=True):
arrays = []
if index:
arrays.append(self.index)
fields = ["Index"] + list(self.columns)
else:
fields = self.columns

itertuple = collections.namedtuple("Itertuple", fields, rename=True)

# use integer indexing because of possible duplicate column names
arrays.extend(self.iloc[:, k] for k in range(len(self.columns)))

return (itertuple(*row) for row in zip(*arrays))

Example

In [3]: df = pd.DataFrame({'col1': [1, 2], 'col2': [0.1, 0.2]}, index=['a', 'b'])

In [4]: for row in df.itertuples():
...: print(row)
...:
Itertuple(Index='a', col1=1, col2=0.10000000000000001)
Itertuple(Index='b', col1=2, col2=0.20000000000000001)

In [5]: row.Index, row.col1, row.col2
Out[5]: ('b', 2, 0.20000000000000001)

There is no performance overhead. I'm not sure about the compatibility for older versions of Python, though. The rename parameter is needed for renaming disallowed field names and duplicate identifiers to standard position-based identifiers, and this feature was added in Python 2.7/3.1.