I have a numpy matrix as the following:
dates = np.matrix([['09/01/70'], ['10/01/70'], ['11/01/70']])
And I want to convert this matrix to a matrix which involves week numbers instead of the dates.
Thanks to "isocalendar()" function in python, you can find the week number of the date.
But when I used the function as the following;
weeks = dates.isocalendar()[1],
I get this error:
AttributeError: 'matrix' object has no attribute 'isocalendar'
What is the right way of converting the date matrix to datenumber matrix in numpy python?
I would use pandas
in this case, converting the matrix into a DataFrame with:
df = pd.DataFrame(dates)
Then I'd convert the dates into datetime
objects:
df[0] = pd.to_datetime(df[0])
And then finally apply the isocalendar()
function:
df = df[0].apply(lambda x: x.isocalendar()[1])
This returns:
0 36
1 40
2 44
Name: 0, dtype: int64
Then you can get an array of this with df.values
or df.as_matrix()
. Hope that helps even if it needs the use of a new package.
There are 2 issues: 1) converting strings to datetime objects, 2) iterating over elements of a matrix
.
You've given us a matrix that contains strings:
dates = np.matrix([['09/01/70'], ['10/01/70'], ['11/01/70']])
In [286]: dates
Out[286]:
matrix([['09/01/70'],
['10/01/70'],
['11/01/70']],
dtype='|S8')
Neither the matrix
nor the strings have datetime functionality. Those strings have to be converted individually.
def getweek(dstr):
return datetime.datetime.strptime(dstr,"%d/%m/%y").isocalendar()[1]
In [288]: getweek("15/10/15")
Out[288]: 42
Applying it to the matrix
is a bit of a bother since I have to index both row and column.
Just be clear about what is going on, lets iterate over the matrix and return both the date string and the week.
In [285]: [(x[0,0],getweek(x[0,0])) for x in dates]
Out[285]: [('09/01/70', 2), ('10/01/70', 2), ('11/01/70', 2)]
getweek
could be tweaked to work along with apply_along_axis
as suggested in the answer to your other date question.
Are you using np.matrix
for a special reason? Why not np.array
? A problem with matrix
is that it keeps returning another matrix - another 2d object, even if it only has 1 element.
There is a nice way of turning it into a 1d array:
In [322]: dates.A1
Out[322]:
array(['09/01/70', '10/01/70', '11/01/70'],
dtype='|S8')
With a 1d array:
In [293]: dates = np.array(['09/01/70', '10/01/70', '11/01/70'])
In [294]: [(x,getweek(x)) for x in dates]
Out[294]: [('09/01/70', 2), ('10/01/70', 2), ('11/01/70', 2)]
In [295]: np.array([getweek(x) for x in dates])
Out[295]: array([2, 2, 2])
Usually date strings like this come from a csv file. We can use genfromtxt
and getweek
to load them
Simulate the file with a text lines, and define converters
for genfromtxt
.
In [339]: txt=b"""09/01/70
.....: 10/02/70
.....: 11/03/70
.....: """
In [340]: np.genfromtxt(txt.splitlines(),dtype=None,converters={0:getweek})
Out[340]: array([ 2, 7, 11])
Here's a way of using np.datetime64
dtype to get weeks
In [350]: txt=b"""1970-09-01
1970-10-15
1970-11-25
1970-01-10"""
In [351]: d=np.genfromtxt(txt.splitlines(),dtype='datetime64[D]')
# load the dates as Days; yyyy-mm-dd is the default format
In [352]: d
Out[352]: array(['1970-09-01', '1970-10-15', '1970-11-25', '1970-01-10'], dtype='datetime64[D]')
In [353]: d.astype('datetime64[W]')-d.astype('datetime64[Y]')
Out[353]: array([34, 41, 46, 1], dtype='timedelta64[W]')
d.astype('datetime64[W]')
converts day units to weeks - though it displays as the first day of the week
d.astype('datetime64[Y]'
- is year units, but displays as the start of the year.
Their difference is the number of weeks (0 is a day in the 1st week of the year). There may be a more compact way of deriving this, but I find this approach instructive.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.